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