Implement a "shares-console" option for non-exclusive console access.
[oweals/dinit.git] / src / baseproc-service.cc
1 #include <cstring>
2 #include <cstdlib>
3
4 #include <sys/un.h>
5 #include <sys/socket.h>
6 #include <sys/types.h>
7 #include <sys/stat.h>
8 #include <unistd.h>
9
10 #include "dinit.h"
11 #include "dinit-log.h"
12 #include "dinit-socket.h"
13 #include "proc-service.h"
14
15 #include "baseproc-sys.h"
16
17 /*
18  * Base process implementation (base_process_service).
19  *
20  * See proc-service.h for interface documentation.
21  */
22
23 void base_process_service::do_smooth_recovery() noexcept
24 {
25     if (! restart_ps_process()) {
26         emergency_stop();
27         services->process_queues();
28     }
29 }
30
31 bool base_process_service::bring_up() noexcept
32 {
33     if (restarting) {
34         if (pid == -1) {
35             return restart_ps_process();
36         }
37         return true;
38     }
39     else {
40         if (! open_socket()) {
41             return false;
42         }
43
44         event_loop.get_time(restart_interval_time, clock_type::MONOTONIC);
45         restart_interval_count = 0;
46         if (start_ps_process(exec_arg_parts,
47                 onstart_flags.starts_on_console || onstart_flags.shares_console)) {
48             // Note: we don't set a start timeout for PROCESS services.
49             if (start_timeout != time_val(0,0) && get_type() != service_type_t::PROCESS) {
50                 restart_timer.arm_timer_rel(event_loop, start_timeout);
51                 stop_timer_armed = true;
52             }
53             else if (stop_timer_armed) {
54                 restart_timer.stop_timer(event_loop);
55                 stop_timer_armed = false;
56             }
57             return true;
58         }
59         return false;
60     }
61 }
62
63 bool base_process_service::start_ps_process(const std::vector<const char *> &cmd, bool on_console) noexcept
64 {
65     // In general, you can't tell whether fork/exec is successful. We use a pipe to communicate
66     // success/failure from the child to the parent. The pipe is set CLOEXEC so a successful
67     // exec closes the pipe, and the parent sees EOF. If the exec is unsuccessful, the errno
68     // is written to the pipe, and the parent can read it.
69
70     event_loop.get_time(last_start_time, clock_type::MONOTONIC);
71
72     int pipefd[2];
73     if (bp_sys::pipe2(pipefd, O_CLOEXEC)) {
74         log(loglevel_t::ERROR, get_name(), ": can't create status check pipe: ", strerror(errno));
75         return false;
76     }
77
78     const char * logfile = this->logfile.c_str();
79     if (*logfile == 0) {
80         logfile = "/dev/null";
81     }
82
83     bool child_status_registered = false;
84     control_conn_t *control_conn = nullptr;
85
86     int control_socket[2] = {-1, -1};
87     if (onstart_flags.pass_cs_fd) {
88         if (dinit_socketpair(AF_UNIX, SOCK_STREAM, /* protocol */ 0, control_socket, SOCK_NONBLOCK)) {
89             log(loglevel_t::ERROR, get_name(), ": can't create control socket: ", strerror(errno));
90             goto out_p;
91         }
92
93         // Make the server side socket close-on-exec:
94         int fdflags = bp_sys::fcntl(control_socket[0], F_GETFD);
95         bp_sys::fcntl(control_socket[0], F_SETFD, fdflags | FD_CLOEXEC);
96
97         try {
98             control_conn = new control_conn_t(event_loop, services, control_socket[0]);
99         }
100         catch (std::exception &exc) {
101             log(loglevel_t::ERROR, get_name(), ": can't launch process; out of memory");
102             goto out_cs;
103         }
104     }
105
106     // Set up complete, now fork and exec:
107
108     pid_t forkpid;
109
110     try {
111         child_status_listener.add_watch(event_loop, pipefd[0], dasynq::IN_EVENTS);
112         child_status_registered = true;
113
114         // We specify a high priority (i.e. low priority value) so that process termination is
115         // handled early. This means we have always recorded that the process is terminated by the
116         // time that we handle events that might otherwise cause us to signal the process, so we
117         // avoid sending a signal to an invalid (and possibly recycled) process ID.
118         forkpid = child_listener.fork(event_loop, reserved_child_watch, dasynq::DEFAULT_PRIORITY - 10);
119         reserved_child_watch = true;
120     }
121     catch (std::exception &e) {
122         log(loglevel_t::ERROR, get_name(), ": Could not fork: ", e.what());
123         goto out_cs_h;
124     }
125
126     if (forkpid == 0) {
127         const char * working_dir_c = nullptr;
128         if (! working_dir.empty()) working_dir_c = working_dir.c_str();
129         run_child_proc(cmd.data(), working_dir_c, logfile, on_console, pipefd[1], control_socket[1],
130                 socket_fd, run_as_uid, run_as_gid);
131     }
132     else {
133         // Parent process
134         bp_sys::close(pipefd[1]); // close the 'other end' fd
135         if (control_socket[1] != -1) {
136             bp_sys::close(control_socket[1]);
137         }
138         pid = forkpid;
139
140         waiting_for_execstat = true;
141         return true;
142     }
143
144     // Failure exit:
145
146     out_cs_h:
147     if (child_status_registered) {
148         child_status_listener.deregister(event_loop);
149     }
150
151     if (onstart_flags.pass_cs_fd) {
152         delete control_conn;
153
154         out_cs:
155         bp_sys::close(control_socket[0]);
156         bp_sys::close(control_socket[1]);
157     }
158
159     out_p:
160     bp_sys::close(pipefd[0]);
161     bp_sys::close(pipefd[1]);
162
163     return false;
164 }
165
166 base_process_service::base_process_service(service_set *sset, string name,
167         service_type_t service_type_p, string &&command,
168         const std::list<std::pair<unsigned,unsigned>> &command_offsets,
169         const std::list<prelim_dep> &deplist_p)
170      : service_record(sset, name, service_type_p, deplist_p), child_listener(this),
171        child_status_listener(this), restart_timer(this)
172 {
173     program_name = std::move(command);
174     exec_arg_parts = separate_args(program_name, command_offsets);
175
176     restart_interval_count = 0;
177     restart_interval_time = {0, 0};
178     restart_timer.service = this;
179     restart_timer.add_timer(event_loop);
180
181     // By default, allow a maximum of 3 restarts within 10.0 seconds:
182     restart_interval.seconds() = 10;
183     restart_interval.nseconds() = 0;
184     max_restart_interval_count = 3;
185
186     waiting_restart_timer = false;
187     reserved_child_watch = false;
188     tracking_child = false;
189     stop_timer_armed = false;
190 }
191
192 void base_process_service::do_restart() noexcept
193 {
194     waiting_restart_timer = false;
195     restart_interval_count++;
196     auto service_state = get_state();
197
198     if (service_state == service_state_t::STARTING) {
199         // for a smooth recovery, we want to check dependencies are available before actually
200         // starting:
201         if (! check_deps_started()) {
202             waiting_for_deps = true;
203             return;
204         }
205     }
206
207     if (! start_ps_process(exec_arg_parts, have_console || onstart_flags.shares_console)) {
208         restarting = false;
209         if (service_state == service_state_t::STARTING) {
210             failed_to_start();
211         }
212         else {
213             // desired_state = service_state_t::STOPPED;
214             forced_stop();
215         }
216         services->process_queues();
217     }
218 }
219
220 bool base_process_service::restart_ps_process() noexcept
221 {
222     using time_val = dasynq::time_val;
223
224     time_val current_time;
225     event_loop.get_time(current_time, clock_type::MONOTONIC);
226
227     if (max_restart_interval_count != 0) {
228         // Check whether we're still in the most recent restart check interval:
229         time_val int_diff = current_time - restart_interval_time;
230         if (int_diff < restart_interval) {
231             if (restart_interval_count >= max_restart_interval_count) {
232                 log(loglevel_t::ERROR, "Service ", get_name(), " restarting too quickly; stopping.");
233                 return false;
234             }
235         }
236         else {
237             restart_interval_time = current_time;
238             restart_interval_count = 0;
239         }
240     }
241
242     // Check if enough time has lapsed since the previous restart. If not, start a timer:
243     time_val tdiff = current_time - last_start_time;
244     if (restart_delay <= tdiff) {
245         // > restart delay (normally 200ms)
246         do_restart();
247     }
248     else {
249         time_val timeout = restart_delay - tdiff;
250         restart_timer.arm_timer_rel(event_loop, timeout);
251         waiting_restart_timer = true;
252     }
253     return true;
254 }
255
256 bool base_process_service::interrupt_start() noexcept
257 {
258     if (waiting_restart_timer) {
259         restart_timer.stop_timer(event_loop);
260         waiting_restart_timer = false;
261         return service_record::interrupt_start();
262     }
263     else {
264         log(loglevel_t::WARN, "Interrupting start of service ", get_name(), " with pid ", pid, " (with SIGINT).");
265         kill_pg(SIGINT);
266
267         if (stop_timeout != time_val(0,0)) {
268             restart_timer.arm_timer_rel(event_loop, stop_timeout);
269             stop_timer_armed = true;
270         }
271         else if (stop_timer_armed) {
272             restart_timer.stop_timer(event_loop);
273             stop_timer_armed = false;
274         }
275
276         set_state(service_state_t::STOPPING);
277         return false;
278     }
279 }
280
281 void base_process_service::kill_with_fire() noexcept
282 {
283     if (pid != -1) {
284         log(loglevel_t::WARN, "Service ", get_name(), " with pid ", pid, " exceeded allowed stop time; killing.");
285         kill_pg(SIGKILL);
286     }
287 }
288
289 void base_process_service::kill_pg(int signo) noexcept
290 {
291     if (onstart_flags.signal_process_only) {
292         bp_sys::kill(pid, signo);
293     }
294     else {
295         pid_t pgid = bp_sys::getpgid(pid);
296         if (pgid == -1) {
297             // only should happen if pid is invalid, which should never happen...
298             log(loglevel_t::ERROR, get_name(), ": can't signal process: ", strerror(errno));
299             return;
300         }
301         bp_sys::kill(-pgid, signo);
302     }
303 }
304
305 void base_process_service::timer_expired() noexcept
306 {
307     stop_timer_armed = false;
308
309     // Timer expires if:
310     // We are stopping, including after having startup cancelled (stop timeout, state is STOPPING); We are
311     // starting (start timeout, state is STARTING); We are waiting for restart timer before restarting,
312     // including smooth recovery (restart timeout, state is STARTING or STARTED).
313     if (get_state() == service_state_t::STOPPING) {
314         kill_with_fire();
315     }
316     else if (pid != -1) {
317         // Starting, start timed out.
318         log(loglevel_t::WARN, "Service ", get_name(), " with pid ", pid, " exceeded allowed start time; cancelling.");
319         interrupt_start();
320         stop_reason = stopped_reason_t::TIMEDOUT;
321         failed_to_start(false, false);
322     }
323     else {
324         // STARTING / STARTED, and we have a pid: must be restarting (smooth recovery if STARTED)
325         do_restart();
326     }
327 }
328
329 void base_process_service::emergency_stop() noexcept
330 {
331     if (! do_auto_restart() && start_explicit) {
332         start_explicit = false;
333         release(false);
334     }
335     forced_stop();
336     stop_dependents();
337 }
338
339 void base_process_service::becoming_inactive() noexcept
340 {
341     if (socket_fd != -1) {
342         close(socket_fd);
343         socket_fd = -1;
344     }
345 }
346
347 bool base_process_service::open_socket() noexcept
348 {
349     if (socket_path.empty() || socket_fd != -1) {
350         // No socket, or already open
351         return true;
352     }
353
354     const char * saddrname = socket_path.c_str();
355
356     // Check the specified socket path
357     struct stat stat_buf;
358     if (stat(saddrname, &stat_buf) == 0) {
359         if ((stat_buf.st_mode & S_IFSOCK) == 0) {
360             // Not a socket
361             log(loglevel_t::ERROR, get_name(), ": Activation socket file exists (and is not a socket)");
362             return false;
363         }
364     }
365     else if (errno != ENOENT) {
366         // Other error
367         log(loglevel_t::ERROR, get_name(), ": Error checking activation socket: ", strerror(errno));
368         return false;
369     }
370
371     // Remove stale socket file (if it exists).
372     // We won't test the return from unlink - if it fails other than due to ENOENT, we should get an
373     // error when we try to create the socket anyway.
374     unlink(saddrname);
375
376     uint sockaddr_size = offsetof(struct sockaddr_un, sun_path) + socket_path.length() + 1;
377     struct sockaddr_un * name = static_cast<sockaddr_un *>(malloc(sockaddr_size));
378     if (name == nullptr) {
379         log(loglevel_t::ERROR, get_name(), ": Opening activation socket: out of memory");
380         return false;
381     }
382
383     name->sun_family = AF_UNIX;
384     strcpy(name->sun_path, saddrname);
385
386     int sockfd = dinit_socket(AF_UNIX, SOCK_STREAM, 0, SOCK_NONBLOCK | SOCK_CLOEXEC);
387     if (sockfd == -1) {
388         log(loglevel_t::ERROR, get_name(), ": Error creating activation socket: ", strerror(errno));
389         free(name);
390         return false;
391     }
392
393     if (bind(sockfd, (struct sockaddr *) name, sockaddr_size) == -1) {
394         log(loglevel_t::ERROR, get_name(), ": Error binding activation socket: ", strerror(errno));
395         close(sockfd);
396         free(name);
397         return false;
398     }
399
400     free(name);
401
402     // POSIX (1003.1, 2013) says that fchown and fchmod don't necessarily work on sockets. We have to
403     // use chown and chmod instead.
404     if (chown(saddrname, socket_uid, socket_gid)) {
405         log(loglevel_t::ERROR, get_name(), ": Error setting activation socket owner/group: ", strerror(errno));
406         close(sockfd);
407         return false;
408     }
409
410     if (chmod(saddrname, socket_perms) == -1) {
411         log(loglevel_t::ERROR, get_name(), ": Error setting activation socket permissions: ", strerror(errno));
412         close(sockfd);
413         return false;
414     }
415
416     if (listen(sockfd, 128) == -1) { // 128 "seems reasonable".
417         log(loglevel_t::ERROR, ": Error listening on activation socket: ", strerror(errno));
418         close(sockfd);
419         return false;
420     }
421
422     socket_fd = sockfd;
423     return true;
424 }