11 #include <sys/socket.h>
19 #include "dinit-log.h"
23 #include <sys/reboot.h>
27 * "simpleinit" from util-linux-ng package handles signals as follows:
28 * SIGTSTP - spawn no more gettys (in preparation for shutdown etc).
29 * In dinit terms this should probably mean "no more auto restarts"
30 * (for any service). (Actually the signal acts as a toggle, if
31 * respawn is disabled it will be re-enabled and init will
32 * act as if SIGHUP had also been sent)
33 * SIGTERM - kill spawned gettys (which are still alive)
34 * Interestingly, simpleinit just sends a SIGTERM to the gettys,
35 * which will not normall kill shells (eg bash ignores SIGTERM).
36 * "/sbin/initctl -r" - rollback services (ran by "shutdown"/halt etc);
37 * shouldn't return until all services have been stopped.
38 * shutdown calls this after sending SIGTERM to processes running
39 * with uid >= 100 ("mortals").
40 * SIGQUIT - init will exec() shutdown. shutdown will detect that it is
41 * running as pid 1 and will just loop and reap child processes.
42 * This is used by shutdown so that init will not hang on to its
43 * inode, allowing the filesystem to be re-mounted readonly
44 * (this is only an issue if the init binary has been unlinked,
45 * since it's then holding an inode which can't be maintained
46 * when the filesystem is unmounted).
48 * Not sent by shutdown:
49 * SIGHUP - re-read inittab and spawn any new getty entries
50 * SIGINT - (ctrl+alt+del handler) - fork & exec "reboot"
52 * On the contrary dinit currently uses:
53 * SIGTERM - roll back services and then fork/exec /sbin/halt
54 * SIGINT - roll back services and then fork/exec /sbin/reboot
55 * SIGQUIT - exec() /sbin/shutdown as per above.
57 * It's an open question about whether dinit should roll back services *before*
58 * running halt/reboot, since those commands should prompt rollback of services
59 * anyway. But it seems safe to do so.
63 static void sigint_reboot_cb(struct ev_loop *loop, ev_signal *w, int revents);
64 static void sigquit_cb(struct ev_loop *loop, ev_signal *w, int revents);
65 static void sigterm_cb(struct ev_loop *loop, ev_signal *w, int revents);
66 void open_control_socket(struct ev_loop *loop) noexcept;
67 void close_control_socket(struct ev_loop *loop) noexcept;
69 struct ev_io control_socket_io;
74 static ServiceSet *service_set;
76 static bool am_system_init = false; // true if we are the system init process
78 static bool control_socket_open = false;
79 int active_control_conns = 0;
81 static const char *control_socket_path = "/dev/dinitctl";
82 static std::string control_socket_str;
85 int main(int argc, char **argv)
89 am_system_init = (getpid() == 1);
92 // setup STDIN, STDOUT, STDERR so that we can use them
93 int onefd = open("/dev/console", O_RDONLY, 0);
95 int twofd = open("/dev/console", O_RDWR, 0);
100 /* Set up signal handlers etc */
101 /* SIG_CHILD is ignored by default: good */
102 /* sigemptyset(&sigwait_set); */
103 /* sigaddset(&sigwait_set, SIGCHLD); */
104 /* sigaddset(&sigwait_set, SIGINT); */
105 /* sigaddset(&sigwait_set, SIGTERM); */
106 /* sigprocmask(SIG_BLOCK, &sigwait_set, NULL); */
108 /* list of services to start */
109 list<const char *> services_to_start;
111 if (! am_system_init) {
112 char * userhome = getenv("HOME");
113 if (userhome == nullptr) {
114 struct passwd * pwuid_p = getpwuid(getuid());
115 if (pwuid_p != nullptr) {
116 userhome = pwuid_p->pw_dir;
120 if (userhome != nullptr) {
121 control_socket_str = userhome;
122 control_socket_str += "/.dinitctl";
123 control_socket_path = control_socket_str.c_str();
127 /* service directory name */
128 const char * service_dir = "/etc/dinit.d";
130 // Arguments, if given, specify a list of services to start.
131 // If we are running as init (PID=1), the kernel gives us any command line
132 // arguments it was given but didn't recognize, including "single" (usually
133 // for "boot to single user mode" aka just start the shell). We can treat
134 // them as service names. In the worst case we can't find any of the named
135 // services, and so we'll start the "boot" service by default.
137 for (int i = 1; i < argc; i++) {
138 if (argv[i][0] == '-') {
140 if (strcmp(argv[i], "--services-dir") == 0 ||
141 strcmp(argv[i], "-d") == 0) {
144 service_dir = argv[i];
147 cerr << "dinit: '--services-dir' (-d) requires an argument" << endl;
151 else if (strcmp(argv[i], "--help") == 0) {
152 cout << "dinit, an init with dependency management" << endl;
153 cout << " --help : display help" << endl;
154 cout << " --services-dir <dir>, -d <dir> : set base directory for service description files (-d <dir>)" << endl;
155 cout << " <service-name> : start service with name <service-name>" << endl;
160 if (! am_system_init) {
161 cerr << "dinit: Unrecognized option: " << argv[i] << endl;
167 // LILO puts "auto" on the kernel command line for unattended boots; we'll filter it.
168 if (! am_system_init || strcmp(argv[i], "auto") != 0) {
169 services_to_start.push_back(argv[i]);
175 if (services_to_start.empty()) {
176 services_to_start.push_back("boot");
179 // Set up signal handlers
180 ev_signal sigint_ev_signal;
181 if (am_system_init) {
182 ev_signal_init(&sigint_ev_signal, sigint_reboot_cb, SIGINT);
185 ev_signal_init(&sigint_ev_signal, sigterm_cb, SIGINT);
188 ev_signal sigquit_ev_signal;
189 if (am_system_init) {
190 // PID 1: SIGQUIT exec's shutdown
191 ev_signal_init(&sigquit_ev_signal, sigquit_cb, SIGQUIT);
194 // Otherwise: SIGQUIT terminates dinit
195 ev_signal_init(&sigquit_ev_signal, sigterm_cb, SIGQUIT);
198 ev_signal sigterm_ev_signal;
199 ev_signal_init(&sigterm_ev_signal, sigterm_cb, SIGTERM);
202 struct ev_loop *loop = ev_default_loop(EVFLAG_AUTO /* | EVFLAG_SIGNALFD */);
203 ev_signal_start(loop, &sigint_ev_signal);
204 ev_signal_start(loop, &sigquit_ev_signal);
205 ev_signal_start(loop, &sigterm_ev_signal);
207 // Try to open control socket (may fail due to readonly filesystem)
208 open_control_socket(loop);
211 if (am_system_init) {
212 // Disable non-critical kernel output to console
213 klogctl(6 /* SYSLOG_ACTION_CONSOLE_OFF */, nullptr, 0);
214 // Make ctrl+alt+del combination send SIGINT to PID 1 (this process)
215 reboot(RB_DISABLE_CAD);
219 /* start requested services */
220 service_set = new ServiceSet(service_dir);
221 for (list<const char *>::iterator i = services_to_start.begin();
222 i != services_to_start.end();
225 service_set->startService(*i);
227 catch (ServiceNotFound &snf) {
228 log(LogLevel::ERROR, snf.serviceName, ": Could not find service description.");
230 catch (ServiceLoadExc &sle) {
231 log(LogLevel::ERROR, sle.serviceName, ": ", sle.excDescription);
233 catch (std::bad_alloc &badalloce) {
234 log(LogLevel::ERROR, "Out of memory when trying to start service: ", *i, ".");
240 // Process events until all services have terminated.
241 while (service_set->count_active_services() != 0) {
242 ev_loop(loop, EVLOOP_ONESHOT);
245 ShutdownType shutdown_type = service_set->getShutdownType();
247 if (am_system_init) {
248 logMsgBegin(LogLevel::INFO, "No more active services.");
250 if (shutdown_type == ShutdownType::REBOOT) {
251 logMsgEnd(" Will reboot.");
253 else if (shutdown_type == ShutdownType::HALT) {
254 logMsgEnd(" Will halt.");
256 else if (shutdown_type == ShutdownType::POWEROFF) {
257 logMsgEnd(" Will power down.");
260 logMsgEnd(" Re-initiating boot sequence.");
264 close_control_socket(ev_default_loop(EVFLAG_AUTO));
266 if (am_system_init) {
267 if (shutdown_type == ShutdownType::CONTINUE) {
268 // It could be that we started in single user mode, and the
269 // user has now exited the shell. We'll try and re-start the
272 service_set->startService("boot");
273 goto event_loop; // yes, the "evil" goto
276 // Now WTF do we do? try to reboot
277 log(LogLevel::ERROR, "Could not start 'boot' service; rebooting.");
278 shutdown_type = ShutdownType::REBOOT;
282 const char * cmd_arg;
283 if (shutdown_type == ShutdownType::HALT) {
286 else if (shutdown_type == ShutdownType::REBOOT) {
294 // Fork and execute dinit-reboot.
295 execl("/usr/libexec/dinit-reboot", "/usr/libexec/dinit-reboot", cmd_arg, nullptr);
296 log(LogLevel::ERROR, "Could not execl() for reboot: ", strerror(errno));
298 // PID 1 must not actually exit, although we should never reach this point:
300 ev_loop(loop, EVLOOP_ONESHOT);
307 // Callback for control socket
308 static void control_socket_cb(struct ev_loop *loop, ev_io *w, int revents)
310 // TODO limit the number of active connections. Keep a tally, and disable the
311 // control connection listening socket watcher if it gets high, and re-enable
312 // it once it falls below the maximum.
314 // Accept a connection
317 int newfd = accept4(sockfd, nullptr, nullptr, SOCK_NONBLOCK | SOCK_CLOEXEC);
321 new ControlConn(loop, service_set, newfd); // will delete itself when it's finished
323 catch (std::bad_alloc &bad_alloc_exc) {
324 log(LogLevel::ERROR, "Accepting control connection: Out of memory");
330 void open_control_socket(struct ev_loop *loop) noexcept
332 if (! control_socket_open) {
333 const char * saddrname = control_socket_path;
334 uint sockaddr_size = offsetof(struct sockaddr_un, sun_path) + strlen(saddrname) + 1;
336 struct sockaddr_un * name = static_cast<sockaddr_un *>(malloc(sockaddr_size));
337 if (name == nullptr) {
338 log(LogLevel::ERROR, "Opening control socket: out of memory");
342 if (am_system_init) {
343 // Unlink any stale control socket file, but only if we are system init, since otherwise
344 // the 'stale' file may not be stale at all:
348 name->sun_family = AF_UNIX;
349 strcpy(name->sun_path, saddrname);
351 int sockfd = socket(AF_UNIX, SOCK_STREAM | SOCK_NONBLOCK | SOCK_CLOEXEC, 0);
353 log(LogLevel::ERROR, "Error creating control socket: ", strerror(errno));
358 if (bind(sockfd, (struct sockaddr *) name, sockaddr_size) == -1) {
359 log(LogLevel::ERROR, "Error binding control socket: ", strerror(errno));
367 // No connections can be made until we listen, so it is fine to change the permissions now
368 // (and anyway there is no way to atomically create the socket and set permissions):
369 if (chmod(saddrname, S_IRUSR | S_IWUSR) == -1) {
370 log(LogLevel::ERROR, "Error setting control socket permissions: ", strerror(errno));
375 if (listen(sockfd, 10) == -1) {
376 log(LogLevel::ERROR, "Error listening on control socket: ", strerror(errno));
381 control_socket_open = true;
382 ev_io_init(&control_socket_io, control_socket_cb, sockfd, EV_READ);
383 ev_io_start(loop, &control_socket_io);
387 void close_control_socket(struct ev_loop *loop) noexcept
389 if (control_socket_open) {
390 int fd = control_socket_io.fd;
391 ev_io_stop(loop, &control_socket_io);
394 // Unlink the socket:
395 unlink(control_socket_path);
399 /* handle SIGINT signal (generated by kernel when ctrl+alt+del pressed) */
400 static void sigint_reboot_cb(struct ev_loop *loop, ev_signal *w, int revents)
402 log_to_console = true;
403 service_set->stop_all_services(ShutdownType::REBOOT);
406 /* handle SIGQUIT (if we are system init) */
407 static void sigquit_cb(struct ev_loop *loop, ev_signal *w, int revents)
409 // This allows remounting the filesystem read-only if the dinit binary has been
410 // unlinked. In that case the kernel holds the binary open, so that it can't be
412 close_control_socket(ev_default_loop(EVFLAG_AUTO));
413 execl("/sbin/shutdown", "/sbin/shutdown", (char *) 0);
414 log(LogLevel::ERROR, "Error executing /sbin/shutdown: ", strerror(errno));
417 /* handle SIGTERM/SIGQUIT - stop all services (not used for system daemon) */
418 static void sigterm_cb(struct ev_loop *loop, ev_signal *w, int revents)
420 log_to_console = true;
421 service_set->stop_all_services();