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