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