11 #include <sys/socket.h>
16 #include <sys/prctl.h>
18 #include <sys/reboot.h>
24 #include "dinit-log.h"
25 #include "dinit-socket.h"
28 * When running as the system init process, Dinit processes the following signals:
30 * SIGTERM - roll back services and then fork/exec /sbin/halt
31 * SIGINT - roll back services and then fork/exec /sbin/reboot
32 * SIGQUIT - exec() /sbin/shutdown without rolling back services
34 * It's an open question about whether Dinit should roll back services *before*
35 * running halt/reboot, since those commands should prompt rollback of services
36 * anyway. But it seems safe to do so, and it means the user can at least stop
37 * services even if the halt/reboot commands are unavailable for some reason.
40 using eventloop_t = dasynq::event_loop<dasynq::null_mutex>;
42 eventloop_t event_loop;
44 static void sigint_reboot_cb(eventloop_t &eloop) noexcept;
45 static void sigquit_cb(eventloop_t &eloop) noexcept;
46 static void sigterm_cb(eventloop_t &eloop) noexcept;
47 static void close_control_socket() noexcept;
48 static void wait_for_user_input() noexcept;
50 static void control_socket_cb(eventloop_t *loop, int fd);
52 void open_control_socket(bool report_ro_failure = true) noexcept;
53 void setup_external_log() noexcept;
58 static dirload_service_set *services;
60 static bool am_system_init = false; // true if we are the system init process
62 static bool control_socket_open = false;
63 static bool external_log_open = false;
64 int active_control_conns = 0;
66 // Control socket path. We maintain a string (control_socket_str) in case we need
67 // to allocate storage, but control_socket_path is the authoritative value.
68 static const char *control_socket_path = "/dev/dinitctl";
69 static std::string control_socket_str;
71 static const char *log_socket_path = "/dev/log";
73 static const char *user_home_path = nullptr;
76 // Get user home (and set user_home_path). (The return may become invalid after
77 // changing the evironment (HOME variable) or using the getpwuid() function).
78 const char * get_user_home()
80 if (user_home_path == nullptr) {
81 user_home_path = getenv("HOME");
82 if (user_home_path == nullptr) {
83 struct passwd * pwuid_p = getpwuid(getuid());
84 if (pwuid_p != nullptr) {
85 user_home_path = pwuid_p->pw_dir;
89 return user_home_path;
94 class callback_signal_handler : public eventloop_t::signal_watcher_impl<callback_signal_handler>
96 using rearm = dasynq::rearm;
99 typedef void (*cb_func_t)(eventloop_t &);
105 callback_signal_handler() : cb_func(nullptr) { }
106 callback_signal_handler(cb_func_t pcb_func) : cb_func(pcb_func) { }
108 void setCbFunc(cb_func_t cb_func)
110 this->cb_func = cb_func;
113 rearm received(eventloop_t &eloop, int signo, siginfo_p siginfo)
120 class control_socket_watcher : public eventloop_t::fd_watcher_impl<control_socket_watcher>
122 using rearm = dasynq::rearm;
125 rearm fd_event(eventloop_t &loop, int fd, int flags) noexcept
127 control_socket_cb(&loop, fd);
132 control_socket_watcher control_socket_io;
135 int dinit_main(int argc, char **argv)
139 am_system_init = (getpid() == 1);
140 const char * service_dir = nullptr;
141 string service_dir_str; // to hold storage for above if necessary
142 bool control_socket_path_set = false;
144 // list of services to start
145 list<const char *> services_to_start;
147 // Arguments, if given, specify a list of services to start.
148 // If we are running as init (PID=1), the kernel gives us any command line
149 // arguments it was given but didn't recognize, including "single" (usually
150 // for "boot to single user mode" aka just start the shell). We can treat
151 // them as service names. In the worst case we can't find any of the named
152 // services, and so we'll start the "boot" service by default.
154 for (int i = 1; i < argc; i++) {
155 if (argv[i][0] == '-') {
157 if (strcmp(argv[i], "--services-dir") == 0 ||
158 strcmp(argv[i], "-d") == 0) {
160 service_dir = argv[i];
163 cerr << "dinit: '--services-dir' (-d) requires an argument" << endl;
167 else if (strcmp(argv[i], "--system") == 0 ||
168 strcmp(argv[i], "-s") == 0) {
169 am_system_init = true;
171 else if (strcmp(argv[i], "--socket-path") == 0 ||
172 strcmp(argv[i], "-p") == 0) {
174 control_socket_path = argv[i];
175 control_socket_path_set = true;
178 cerr << "dinit: '--socket-path' (-p) requires an argument" << endl;
182 else if (strcmp(argv[i], "--help") == 0) {
183 cout << "dinit, an init with dependency management" << endl;
184 cout << " --help display help" << endl;
185 cout << " --services-dir <dir>, -d <dir>" << endl;
186 cout << " set base directory for service description" << endl;
187 cout << " files (-d <dir>)" << endl;
188 cout << " --system, -s run as the system init process" << endl;
189 cout << " --socket-path <path>, -p <path>" << endl;
190 cout << " path to control socket" << endl;
191 cout << " <service-name> start service with name <service-name>" << endl;
196 if (! am_system_init) {
197 cerr << "dinit: Unrecognized option: " << argv[i] << endl;
204 // LILO puts "auto" on the kernel command line for unattended boots; we'll filter it.
205 if (! am_system_init || strcmp(argv[i], "auto") != 0) {
206 services_to_start.push_back(argv[i]);
213 if (am_system_init) {
214 // setup STDIN, STDOUT, STDERR so that we can use them
215 int onefd = open("/dev/console", O_RDONLY, 0);
217 int twofd = open("/dev/console", O_RDWR, 0);
221 if (onefd > 2) close(onefd);
222 if (twofd > 2) close(twofd);
225 /* Set up signal handlers etc */
226 /* SIG_CHILD is ignored by default: good */
227 sigset_t sigwait_set;
228 sigemptyset(&sigwait_set);
229 sigaddset(&sigwait_set, SIGCHLD);
230 sigaddset(&sigwait_set, SIGINT);
231 sigaddset(&sigwait_set, SIGTERM);
232 if (am_system_init) sigaddset(&sigwait_set, SIGQUIT);
233 sigprocmask(SIG_BLOCK, &sigwait_set, NULL);
235 // Terminal access control signals - we block these so that dinit can't be
236 // suspended if it writes to the terminal after some other process has claimed
238 signal(SIGTSTP, SIG_IGN);
239 signal(SIGTTIN, SIG_IGN);
240 signal(SIGTTOU, SIG_IGN);
242 signal(SIGPIPE, SIG_IGN);
244 if (! am_system_init && ! control_socket_path_set) {
245 const char * userhome = get_user_home();
246 if (userhome != nullptr) {
247 control_socket_str = userhome;
248 control_socket_str += "/.dinitctl";
249 control_socket_path = control_socket_str.c_str();
253 /* service directory name */
254 if (service_dir == nullptr && ! am_system_init) {
255 const char * userhome = get_user_home();
256 if (userhome != nullptr) {
257 service_dir_str = get_user_home();
258 service_dir_str += "/dinit.d";
259 service_dir = service_dir_str.c_str();
263 if (service_dir == nullptr) {
264 service_dir = "/etc/dinit.d";
267 if (services_to_start.empty()) {
268 services_to_start.push_back("boot");
271 // Set up signal handlers
272 callback_signal_handler sigterm_watcher {sigterm_cb};
273 callback_signal_handler sigint_watcher;
274 callback_signal_handler sigquit_watcher;
276 if (am_system_init) {
277 sigint_watcher.setCbFunc(sigint_reboot_cb);
278 sigquit_watcher.setCbFunc(sigquit_cb);
281 sigint_watcher.setCbFunc(sigterm_cb);
284 sigint_watcher.add_watch(event_loop, SIGINT);
285 sigterm_watcher.add_watch(event_loop, SIGTERM);
287 if (am_system_init) {
288 // PID 1: SIGQUIT exec's shutdown
289 sigquit_watcher.add_watch(event_loop, SIGQUIT);
290 // As a user process, we instead just let SIGQUIT perform the default action.
293 // Try to open control socket (may fail due to readonly filesystem)
294 open_control_socket(false);
297 if (am_system_init) {
298 // Disable non-critical kernel output to console
299 klogctl(6 /* SYSLOG_ACTION_CONSOLE_OFF */, nullptr, 0);
300 // Make ctrl+alt+del combination send SIGINT to PID 1 (this process)
301 reboot(RB_DISABLE_CAD);
304 // Mark ourselves as a subreaper. This means that if a process we start double-forks, the
305 // orphaned child will re-parent to us rather than to PID 1 (although that could be us too).
306 prctl(PR_SET_CHILD_SUBREAPER, 1);
309 /* start requested services */
310 services = new dirload_service_set(service_dir);
314 for (auto svc : services_to_start) {
316 services->start_service(svc);
317 // Note in general if we fail to start a service we don't need any special error handling,
318 // since we either leave other services running or, if it was the only service, then no
319 // services will be running and we will process normally (reboot if system process,
320 // exit if user process).
322 catch (service_not_found &snf) {
323 log(loglevel_t::ERROR, snf.serviceName, ": Could not find service description.");
325 catch (service_load_exc &sle) {
326 log(loglevel_t::ERROR, sle.serviceName, ": ", sle.excDescription);
328 catch (std::bad_alloc &badalloce) {
329 log(loglevel_t::ERROR, "Out of memory when trying to start service: ", svc, ".");
336 // Process events until all services have terminated.
337 while (services->count_active_services() != 0) {
341 shutdown_type_t shutdown_type = services->getShutdownType();
343 if (am_system_init) {
344 log_msg_begin(loglevel_t::INFO, "No more active services.");
346 if (shutdown_type == shutdown_type_t::REBOOT) {
347 log_msg_end(" Will reboot.");
349 else if (shutdown_type == shutdown_type_t::HALT) {
350 log_msg_end(" Will halt.");
352 else if (shutdown_type == shutdown_type_t::POWEROFF) {
353 log_msg_end(" Will power down.");
356 log_msg_end(" Re-initiating boot sequence.");
360 while (! is_log_flushed()) {
364 close_control_socket();
366 if (am_system_init) {
367 if (shutdown_type == shutdown_type_t::CONTINUE) {
368 // It could be that we started in single user mode, and the
369 // user has now exited the shell. We'll try and re-start the
372 services->start_service("boot");
373 goto event_loop; // yes, the "evil" goto
376 // Now what do we do? try to reboot, but wait for user ack to avoid boot loop.
377 log(loglevel_t::ERROR, "Could not start 'boot' service. Will attempt reboot.");
378 wait_for_user_input();
379 shutdown_type = shutdown_type_t::REBOOT;
383 const char * cmd_arg;
384 if (shutdown_type == shutdown_type_t::HALT) {
387 else if (shutdown_type == shutdown_type_t::REBOOT) {
395 // Fork and execute dinit-reboot.
396 execl("/sbin/shutdown", "/sbin/shutdown", "--system", cmd_arg, nullptr);
397 log(loglevel_t::ERROR, "Could not execute /sbin/shutdown: ", strerror(errno));
399 // PID 1 must not actually exit, although we should never reach this point:
404 else if (shutdown_type == shutdown_type_t::REBOOT) {
405 // Non-system-process. If we got SIGINT, let's die due to it:
406 sigset_t sigwait_set;
407 sigemptyset(&sigwait_set);
408 sigaddset(&sigwait_set, SIGINT);
410 sigprocmask(SIG_UNBLOCK, &sigwait_set, NULL);
416 // In exception situations we want user confirmation before proceeding (eg on critical boot failure
417 // we wait before rebooting to avoid a reboot loop).
418 static void wait_for_user_input() noexcept
420 std::cout << "Press Enter to continue." << std::endl;
422 read(STDIN_FILENO, buf, 1);
425 // Callback for control socket
426 static void control_socket_cb(eventloop_t *loop, int sockfd)
428 // Considered keeping a limit the number of active connections, however, there doesn't
429 // seem much to be gained from that. Only root can create connections and not being
430 // able to establish a control connection is as much a denial-of-service as is not being
431 // able to start a service due to lack of fd's.
433 // Accept a connection
434 int newfd = dinit_accept4(sockfd, nullptr, nullptr, SOCK_NONBLOCK | SOCK_CLOEXEC);
438 new control_conn_t(*loop, services, newfd); // will delete itself when it's finished
440 catch (std::exception &exc) {
441 log(loglevel_t::ERROR, "Accepting control connection: ", exc.what());
447 void open_control_socket(bool report_ro_failure) noexcept
449 if (! control_socket_open) {
450 const char * saddrname = control_socket_path;
451 size_t saddrname_len = strlen(saddrname);
452 uint sockaddr_size = offsetof(struct sockaddr_un, sun_path) + saddrname_len + 1;
454 struct sockaddr_un * name = static_cast<sockaddr_un *>(malloc(sockaddr_size));
455 if (name == nullptr) {
456 log(loglevel_t::ERROR, "Opening control socket: out of memory");
460 if (am_system_init) {
461 // Unlink any stale control socket file, but only if we are system init, since otherwise
462 // the 'stale' file may not be stale at all:
466 name->sun_family = AF_UNIX;
467 memcpy(name->sun_path, saddrname, saddrname_len + 1);
469 int sockfd = dinit_socket(AF_UNIX, SOCK_STREAM, 0, SOCK_NONBLOCK | SOCK_CLOEXEC);
471 log(loglevel_t::ERROR, "Error creating control socket: ", strerror(errno));
476 if (bind(sockfd, (struct sockaddr *) name, sockaddr_size) == -1) {
477 if (errno != EROFS || report_ro_failure) {
478 log(loglevel_t::ERROR, "Error binding control socket: ", strerror(errno));
487 // No connections can be made until we listen, so it is fine to change the permissions now
488 // (and anyway there is no way to atomically create the socket and set permissions):
489 if (chmod(saddrname, S_IRUSR | S_IWUSR) == -1) {
490 log(loglevel_t::ERROR, "Error setting control socket permissions: ", strerror(errno));
495 if (listen(sockfd, 10) == -1) {
496 log(loglevel_t::ERROR, "Error listening on control socket: ", strerror(errno));
502 control_socket_io.add_watch(event_loop, sockfd, dasynq::IN_EVENTS);
503 control_socket_open = true;
505 catch (std::exception &e)
507 log(loglevel_t::ERROR, "Could not setup I/O on control socket: ", e.what());
513 static void close_control_socket() noexcept
515 if (control_socket_open) {
516 int fd = control_socket_io.get_watched_fd();
517 control_socket_io.deregister(event_loop);
520 // Unlink the socket:
521 unlink(control_socket_path);
525 void setup_external_log() noexcept
527 if (! external_log_open) {
529 const char * saddrname = log_socket_path;
530 size_t saddrname_len = strlen(saddrname);
531 uint sockaddr_size = offsetof(struct sockaddr_un, sun_path) + saddrname_len + 1;
533 struct sockaddr_un * name = static_cast<sockaddr_un *>(malloc(sockaddr_size));
534 if (name == nullptr) {
535 log(loglevel_t::ERROR, "Connecting to log socket: out of memory");
539 name->sun_family = AF_UNIX;
540 memcpy(name->sun_path, saddrname, saddrname_len + 1);
542 int sockfd = dinit_socket(AF_UNIX, SOCK_DGRAM, 0, SOCK_NONBLOCK | SOCK_CLOEXEC);
544 log(loglevel_t::ERROR, "Error creating log socket: ", strerror(errno));
549 if (connect(sockfd, (struct sockaddr *) name, sockaddr_size) == 0 || errno == EINPROGRESS) {
550 // For EINPROGRESS, connection is still being established; however, we can select on
551 // the file descriptor so we will be notified when it's ready. In other words we can
552 // basically use it anyway.
554 setup_main_log(sockfd);
556 catch (std::exception &e) {
557 log(loglevel_t::ERROR, "Setting up log failed: ", e.what());
562 // Note if connect fails, we haven't warned at all, because the syslog server might not
571 /* handle SIGINT signal (generated by Linux kernel when ctrl+alt+del pressed) */
572 static void sigint_reboot_cb(eventloop_t &eloop) noexcept
574 services->stop_all_services(shutdown_type_t::REBOOT);
577 /* handle SIGQUIT (if we are system init) */
578 static void sigquit_cb(eventloop_t &eloop) noexcept
580 // This performs an immediate shutdown, without service rollback.
581 close_control_socket();
582 execl("/sbin/shutdown", "/sbin/shutdown", "--system", (char *) 0);
583 log(loglevel_t::ERROR, "Error executing /sbin/shutdown: ", strerror(errno));
584 sync(); // since a hard poweroff might be required at this point...
587 /* handle SIGTERM/SIGQUIT(non-system-daemon) - stop all services and shut down */
588 static void sigterm_cb(eventloop_t &eloop) noexcept
590 services->stop_all_services();