dinit.cc 31 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869
  1. #include <iostream>
  2. #include <fstream>
  3. #include <list>
  4. #include <cstring>
  5. #include <csignal>
  6. #include <cstddef>
  7. #include <cstdlib>
  8. #include <sys/types.h>
  9. #include <sys/stat.h>
  10. #include <sys/un.h>
  11. #include <sys/socket.h>
  12. #include <unistd.h>
  13. #include <fcntl.h>
  14. #include <pwd.h>
  15. #include <termios.h>
  16. #ifdef __linux__
  17. #include <sys/prctl.h>
  18. #include <sys/klog.h>
  19. #include <sys/reboot.h>
  20. #endif
  21. #if defined(__FreeBSD__) || defined(__DragonFly__)
  22. #include <sys/procctl.h>
  23. #endif
  24. #include "dinit.h"
  25. #include "dasynq.h"
  26. #include "service.h"
  27. #include "control.h"
  28. #include "dinit-log.h"
  29. #include "dinit-socket.h"
  30. #include "static-string.h"
  31. #include "dinit-utmp.h"
  32. #include "options-processing.h"
  33. #include "mconfig.h"
  34. /*
  35. * When running as the system init process, Dinit processes the following signals:
  36. *
  37. * SIGTERM - roll back services and then fork/exec /sbin/halt
  38. * SIGINT - roll back services and then fork/exec /sbin/reboot
  39. * SIGQUIT - exec() /sbin/shutdown without rolling back services
  40. *
  41. * It's an open question about whether Dinit should roll back services *before*
  42. * running halt/reboot, since those commands should prompt rollback of services
  43. * anyway. But it seems safe to do so, and it means the user can at least stop
  44. * services even if the halt/reboot commands are unavailable for some reason.
  45. */
  46. using namespace cts;
  47. using eventloop_t = dasynq::event_loop<dasynq::null_mutex>;
  48. eventloop_t event_loop;
  49. static void sigint_reboot_cb(eventloop_t &eloop) noexcept;
  50. static void sigquit_cb(eventloop_t &eloop) noexcept;
  51. static void sigterm_cb(eventloop_t &eloop) noexcept;
  52. static void open_control_socket(bool report_ro_failure = true) noexcept;
  53. static void close_control_socket() noexcept;
  54. static void confirm_restart_boot() noexcept;
  55. static void control_socket_cb(eventloop_t *loop, int fd);
  56. // Variables
  57. static dirload_service_set *services;
  58. static bool am_system_mgr = false; // true if we are PID 1
  59. static bool am_system_init = false; // true if we are the system init process
  60. static bool did_log_boot = false;
  61. static bool control_socket_open = false;
  62. bool external_log_open = false;
  63. int active_control_conns = 0;
  64. // Control socket path. We maintain a string (control_socket_str) in case we need
  65. // to allocate storage, but control_socket_path is the authoritative value.
  66. static const char *control_socket_path = SYSCONTROLSOCKET;
  67. static std::string control_socket_str;
  68. static const char *env_file_path = "/etc/dinit/environment";
  69. static const char *log_path = "/dev/log";
  70. static bool log_is_syslog = true; // if false, log is a file
  71. // Set to true (when console_input_watcher is active) if console input becomes available
  72. static bool console_input_ready = false;
  73. namespace {
  74. // Event-loop handler for a signal, which just delegates to a function (pointer).
  75. class callback_signal_handler : public eventloop_t::signal_watcher_impl<callback_signal_handler>
  76. {
  77. using rearm = dasynq::rearm;
  78. public:
  79. typedef void (*cb_func_t)(eventloop_t &);
  80. private:
  81. cb_func_t cb_func;
  82. public:
  83. callback_signal_handler() : cb_func(nullptr) { }
  84. callback_signal_handler(cb_func_t pcb_func) : cb_func(pcb_func) { }
  85. void set_cb_func(cb_func_t cb_func)
  86. {
  87. this->cb_func = cb_func;
  88. }
  89. rearm received(eventloop_t &eloop, int signo, siginfo_p siginfo)
  90. {
  91. cb_func(eloop);
  92. return rearm::REARM;
  93. }
  94. };
  95. // Event-loop handler for when a connection is made to the control socket.
  96. class control_socket_watcher : public eventloop_t::fd_watcher_impl<control_socket_watcher>
  97. {
  98. using rearm = dasynq::rearm;
  99. public:
  100. rearm fd_event(eventloop_t &loop, int fd, int flags) noexcept
  101. {
  102. control_socket_cb(&loop, fd);
  103. return rearm::REARM;
  104. }
  105. };
  106. // Watch for console input and set a flag when it is available.
  107. class console_input_watcher : public eventloop_t::fd_watcher_impl<console_input_watcher>
  108. {
  109. using rearm = dasynq::rearm;
  110. public:
  111. rearm fd_event(eventloop_t &loop, int fd, int flags) noexcept
  112. {
  113. console_input_ready = true;
  114. return rearm::DISARM;
  115. }
  116. };
  117. // Simple timer used to limit the amount of time waiting for the log flush to complete (at shutdown)
  118. class log_flush_timer_t : public eventloop_t::timer_impl<log_flush_timer_t>
  119. {
  120. using rearm = dasynq::rearm;
  121. bool expired;
  122. public:
  123. rearm timer_expiry(eventloop_t &, int expiry_count)
  124. {
  125. expired = true;
  126. return rearm::DISARM;
  127. }
  128. bool has_expired()
  129. {
  130. return expired;
  131. }
  132. void reset()
  133. {
  134. expired = false;
  135. }
  136. };
  137. control_socket_watcher control_socket_io;
  138. console_input_watcher console_input_io;
  139. log_flush_timer_t log_flush_timer;
  140. // These need to be at namespace scope to prevent causing stack allocations when using them:
  141. constexpr auto shutdown_exec = literal(SBINDIR) + "/" + SHUTDOWN_PREFIX + "shutdown";
  142. constexpr auto error_exec_sd = literal("Error executing ") + shutdown_exec + ": ";
  143. }
  144. // Main entry point
  145. int dinit_main(int argc, char **argv)
  146. {
  147. using namespace std;
  148. am_system_mgr = (getpid() == 1);
  149. am_system_init = (getuid() == 0);
  150. const char * env_file = nullptr;
  151. bool control_socket_path_set = false;
  152. bool env_file_set = false;
  153. bool log_specified = false;
  154. service_dir_opt service_dir_opts;
  155. // list of services to start
  156. list<const char *> services_to_start;
  157. // Arguments, if given, specify a list of services to start.
  158. // If we are running as init (PID=1), the Linux kernel gives us any command line arguments it was given
  159. // but didn't recognize, including "single" (usually for "boot to single user mode" aka just start the
  160. // shell). We can treat them as service names. In the worst case we can't find any of the named
  161. // services, and so we'll start the "boot" service by default.
  162. if (argc > 1) {
  163. for (int i = 1; i < argc; i++) {
  164. if (argv[i][0] == '-') {
  165. // An option...
  166. if (strcmp(argv[i], "--env-file") == 0 || strcmp(argv[i], "-e") == 0) {
  167. if (++i < argc) {
  168. env_file_set = true;
  169. env_file = argv[i];
  170. }
  171. else {
  172. cerr << "dinit: '--env-file' (-e) requires an argument" << endl;
  173. }
  174. }
  175. else if (strcmp(argv[i], "--services-dir") == 0 || strcmp(argv[i], "-d") == 0) {
  176. if (++i < argc) {
  177. service_dir_opts.set_specified_service_dir(argv[i]);
  178. }
  179. else {
  180. cerr << "dinit: '--services-dir' (-d) requires an argument" << endl;
  181. return 1;
  182. }
  183. }
  184. else if (strcmp(argv[i], "--system") == 0 || strcmp(argv[i], "-s") == 0) {
  185. am_system_init = true;
  186. }
  187. else if (strcmp(argv[i], "--system-mgr") == 0 || strcmp(argv[i], "-m") == 0) {
  188. am_system_mgr = true;
  189. }
  190. else if (strcmp(argv[i], "--user") == 0 || strcmp(argv[i], "-u") == 0) {
  191. am_system_init = false;
  192. }
  193. else if (strcmp(argv[i], "--container") == 0 || strcmp(argv[i], "-o") == 0) {
  194. am_system_mgr = false;
  195. }
  196. else if (strcmp(argv[i], "--socket-path") == 0 || strcmp(argv[i], "-p") == 0) {
  197. if (++i < argc) {
  198. control_socket_path = argv[i];
  199. control_socket_path_set = true;
  200. }
  201. else {
  202. cerr << "dinit: '--socket-path' (-p) requires an argument" << endl;
  203. return 1;
  204. }
  205. }
  206. else if (strcmp(argv[i], "--log-file") == 0 || strcmp(argv[i], "-l") == 0) {
  207. if (++i < argc) {
  208. log_path = argv[i];
  209. log_is_syslog = false;
  210. log_specified = true;
  211. }
  212. else {
  213. cerr << "dinit: '--log-file' (-l) requires an argument" << endl;
  214. return 1;
  215. }
  216. }
  217. else if (strcmp(argv[i], "--quiet") == 0 || strcmp(argv[i], "-q") == 0) {
  218. console_service_status = false;
  219. log_level[DLOG_CONS] = loglevel_t::ZERO;
  220. }
  221. else if (strcmp(argv[i], "--help") == 0) {
  222. cout << "dinit, an init with dependency management\n"
  223. " --help display help\n"
  224. " --env-file <file>, -e <file>\n"
  225. " environment variable initialisation file\n"
  226. " --services-dir <dir>, -d <dir>\n"
  227. " set base directory for service description\n"
  228. " files\n"
  229. " --system, -s run as the system service manager\n"
  230. " --system-mgr, -m run as system manager (perform shutdown etc)\n"
  231. " --user, -u run as a user service manager\n"
  232. " --container, -o run in container mode (do not manage system)\n"
  233. " --socket-path <path>, -p <path>\n"
  234. " path to control socket\n"
  235. " --log-file <file>, -l <file> log to the specified file\n"
  236. " --quiet, -q disable output to standard output\n"
  237. " <service-name> [...] start service with name <service-name>\n";
  238. return 0;
  239. }
  240. else {
  241. // unrecognized
  242. if (! am_system_init) {
  243. cerr << "dinit: Unrecognized option: " << argv[i] << endl;
  244. return 1;
  245. }
  246. }
  247. }
  248. else {
  249. #ifdef __linux__
  250. // LILO puts "auto" on the kernel command line for unattended boots; we'll filter it.
  251. if (! am_system_mgr || strcmp(argv[i], "auto") != 0) {
  252. services_to_start.push_back(argv[i]);
  253. }
  254. #else
  255. services_to_start.push_back(argv[i]);
  256. #endif
  257. }
  258. }
  259. }
  260. if (am_system_init) {
  261. // setup STDIN, STDOUT, STDERR so that we can use them
  262. int onefd = open("/dev/console", O_RDONLY, 0);
  263. if (onefd != -1) {
  264. dup2(onefd, 0);
  265. }
  266. int twofd = open("/dev/console", O_RDWR, 0);
  267. if (twofd != -1) {
  268. dup2(twofd, 1);
  269. dup2(twofd, 2);
  270. }
  271. if (onefd > 2) close(onefd);
  272. if (twofd > 2) close(twofd);
  273. if (! env_file_set) {
  274. env_file = env_file_path;
  275. }
  276. }
  277. /* Set up signal handlers etc */
  278. /* SIG_CHILD is ignored by default: good */
  279. sigset_t sigwait_set;
  280. sigemptyset(&sigwait_set);
  281. sigaddset(&sigwait_set, SIGCHLD);
  282. sigaddset(&sigwait_set, SIGINT);
  283. sigaddset(&sigwait_set, SIGTERM);
  284. if (am_system_mgr) sigaddset(&sigwait_set, SIGQUIT);
  285. sigprocmask(SIG_BLOCK, &sigwait_set, NULL);
  286. // Terminal access control signals - we ignore these so that dinit can't be
  287. // suspended if it writes to the terminal after some other process has claimed
  288. // ownership of it.
  289. signal(SIGTSTP, SIG_IGN);
  290. signal(SIGTTIN, SIG_IGN);
  291. signal(SIGTTOU, SIG_IGN);
  292. signal(SIGPIPE, SIG_IGN);
  293. if (! am_system_init && ! control_socket_path_set) {
  294. const char * userhome = service_dir_opt::get_user_home();
  295. if (userhome != nullptr) {
  296. control_socket_str = userhome;
  297. control_socket_str += "/.dinitctl";
  298. control_socket_path = control_socket_str.c_str();
  299. }
  300. }
  301. if (services_to_start.empty()) {
  302. services_to_start.push_back("boot");
  303. }
  304. // Set up signal handlers
  305. callback_signal_handler sigterm_watcher {sigterm_cb};
  306. callback_signal_handler sigint_watcher;
  307. callback_signal_handler sigquit_watcher;
  308. if (am_system_mgr) {
  309. sigint_watcher.set_cb_func(sigint_reboot_cb);
  310. sigquit_watcher.set_cb_func(sigquit_cb);
  311. }
  312. else {
  313. sigint_watcher.set_cb_func(sigterm_cb);
  314. }
  315. sigint_watcher.add_watch(event_loop, SIGINT);
  316. sigterm_watcher.add_watch(event_loop, SIGTERM);
  317. if (am_system_mgr) {
  318. // PID 1: we may ask for console input; SIGQUIT exec's shutdown
  319. console_input_io.add_watch(event_loop, STDIN_FILENO, dasynq::IN_EVENTS, false);
  320. sigquit_watcher.add_watch(event_loop, SIGQUIT);
  321. // (If not PID 1, we instead just let SIGQUIT perform the default action.)
  322. }
  323. // Try to open control socket (may fail due to readonly filesystem)
  324. open_control_socket(false);
  325. #ifdef __linux__
  326. if (am_system_mgr) {
  327. // Disable non-critical kernel output to console
  328. klogctl(6 /* SYSLOG_ACTION_CONSOLE_OFF */, nullptr, 0);
  329. // Make ctrl+alt+del combination send SIGINT to PID 1 (this process)
  330. reboot(RB_DISABLE_CAD);
  331. }
  332. // Mark ourselves as a subreaper. This means that if a process we start double-forks, the
  333. // orphaned child will re-parent to us rather than to PID 1 (although that could be us too).
  334. prctl(PR_SET_CHILD_SUBREAPER, 1);
  335. #elif defined(__FreeBSD__) || defined(__DragonFly__)
  336. // Documentation (man page) for this kind of sucks. PROC_REAP_ACQUIRE "acquires the reaper status for
  337. // the current process" but does that mean the first two arguments still need valid values to be
  338. // supplied? We'll play it safe and explicitly target our own process:
  339. procctl(P_PID, getpid(), PROC_REAP_ACQUIRE, NULL);
  340. #endif
  341. log_flush_timer.add_timer(event_loop, dasynq::clock_type::MONOTONIC);
  342. service_dir_opts.build_paths(am_system_init);
  343. /* start requested services */
  344. services = new dirload_service_set(std::move(service_dir_opts.get_paths()));
  345. init_log(services, log_is_syslog);
  346. if (am_system_init) {
  347. log(loglevel_t::INFO, false, "Starting system");
  348. }
  349. // Only try to set up the external log now if we aren't the system init. (If we are the
  350. // system init, wait until the log service starts).
  351. if (! am_system_init && log_specified) setup_external_log();
  352. if (env_file != nullptr) {
  353. read_env_file(env_file);
  354. }
  355. for (auto svc : services_to_start) {
  356. try {
  357. services->start_service(svc);
  358. // Note in general if we fail to start a service we don't need any special error handling,
  359. // since we either leave other services running or, if it was the only service, then no
  360. // services will be running and we will process normally (reboot if system process,
  361. // exit if user process).
  362. }
  363. catch (service_not_found &snf) {
  364. log(loglevel_t::ERROR, snf.service_name, ": Could not find service description.");
  365. }
  366. catch (service_load_exc &sle) {
  367. log(loglevel_t::ERROR, sle.service_name, ": ", sle.exc_description);
  368. }
  369. catch (std::bad_alloc &badalloce) {
  370. log(loglevel_t::ERROR, "Out of memory when trying to start service: ", svc, ".");
  371. break;
  372. }
  373. }
  374. run_event_loop:
  375. // Process events until all services have terminated.
  376. while (services->count_active_services() != 0) {
  377. event_loop.run();
  378. }
  379. shutdown_type_t shutdown_type = services->get_shutdown_type();
  380. if (shutdown_type == shutdown_type_t::REMAIN) {
  381. goto run_event_loop;
  382. }
  383. if (am_system_mgr) {
  384. log_msg_begin(loglevel_t::INFO, "No more active services.");
  385. if (shutdown_type == shutdown_type_t::REBOOT) {
  386. log_msg_end(" Will reboot.");
  387. }
  388. else if (shutdown_type == shutdown_type_t::HALT) {
  389. log_msg_end(" Will halt.");
  390. }
  391. else if (shutdown_type == shutdown_type_t::POWEROFF) {
  392. log_msg_end(" Will power down.");
  393. }
  394. }
  395. log_flush_timer.reset();
  396. log_flush_timer.arm_timer_rel(event_loop, timespec{5,0}); // 5 seconds
  397. while (! is_log_flushed() && ! log_flush_timer.has_expired()) {
  398. event_loop.run();
  399. }
  400. close_control_socket();
  401. if (am_system_mgr) {
  402. if (shutdown_type == shutdown_type_t::NONE) {
  403. // Services all stopped but there was no shutdown issued. Inform user, wait for ack, and
  404. // re-start boot sequence.
  405. sync(); // Sync to minimise data loss if user elects to power off / hard reset
  406. confirm_restart_boot();
  407. if (services->count_active_services() != 0) {
  408. // Recovery service started
  409. goto run_event_loop;
  410. }
  411. shutdown_type = services->get_shutdown_type();
  412. if (shutdown_type == shutdown_type_t::NONE) {
  413. try {
  414. services->start_service("boot");
  415. goto run_event_loop; // yes, the "evil" goto
  416. }
  417. catch (...) {
  418. // Now what do we do? try to reboot, but wait for user ack to avoid boot loop.
  419. log(loglevel_t::ERROR, "Could not start 'boot' service. Will attempt reboot.");
  420. shutdown_type = shutdown_type_t::REBOOT;
  421. }
  422. }
  423. }
  424. const char * cmd_arg;
  425. if (shutdown_type == shutdown_type_t::HALT) {
  426. cmd_arg = "-h";
  427. }
  428. else if (shutdown_type == shutdown_type_t::REBOOT) {
  429. cmd_arg = "-r";
  430. }
  431. else {
  432. // power off.
  433. cmd_arg = "-p";
  434. }
  435. // Fork and execute dinit-reboot.
  436. execl(shutdown_exec.c_str(), shutdown_exec.c_str(), "--system", cmd_arg, nullptr);
  437. log(loglevel_t::ERROR, error_exec_sd, strerror(errno));
  438. // PID 1 must not actually exit, although we should never reach this point:
  439. while (true) {
  440. event_loop.run();
  441. }
  442. }
  443. else if (shutdown_type == shutdown_type_t::REBOOT) {
  444. // Non-system-process. If we got SIGINT, let's die due to it:
  445. sigset_t sigwait_set_int;
  446. sigemptyset(&sigwait_set_int);
  447. sigaddset(&sigwait_set_int, SIGINT);
  448. raise(SIGINT);
  449. sigprocmask(SIG_UNBLOCK, &sigwait_set_int, NULL);
  450. }
  451. return 0;
  452. }
  453. // Log a parse error when reading the environment file.
  454. static void log_bad_env(int linenum)
  455. {
  456. log(loglevel_t::ERROR, "invalid environment variable setting in environment file (line ", linenum, ")");
  457. }
  458. // Read and set environment variables from a file. May throw std::bad_alloc, std::system_error.
  459. void read_env_file(const char *env_file_path)
  460. {
  461. // Note that we can't use the log in this function; it hasn't been initialised yet.
  462. std::ifstream env_file(env_file_path);
  463. if (! env_file) return;
  464. env_file.exceptions(std::ios::badbit);
  465. auto &clocale = std::locale::classic();
  466. std::string line;
  467. int linenum = 0;
  468. while (std::getline(env_file, line)) {
  469. linenum++;
  470. auto lpos = line.begin();
  471. auto lend = line.end();
  472. while (lpos != lend && std::isspace(*lpos, clocale)) {
  473. ++lpos;
  474. }
  475. if (lpos != lend) {
  476. if (*lpos != '#') {
  477. if (*lpos == '=') {
  478. log_bad_env(linenum);
  479. continue;
  480. }
  481. auto name_begin = lpos++;
  482. // skip until '=' or whitespace:
  483. while (lpos != lend && *lpos != '=' && ! std::isspace(*lpos, clocale)) ++lpos;
  484. auto name_end = lpos;
  485. // skip whitespace:
  486. while (lpos != lend && std::isspace(*lpos, clocale)) ++lpos;
  487. if (lpos == lend) {
  488. log_bad_env(linenum);
  489. continue;
  490. }
  491. ++lpos;
  492. auto val_begin = lpos;
  493. while (lpos != lend && *lpos != '\n') ++lpos;
  494. auto val_end = lpos;
  495. std::string name = line.substr(name_begin - line.begin(), name_end - name_begin);
  496. std::string value = line.substr(val_begin - line.begin(), val_end - val_begin);
  497. if (setenv(name.c_str(), value.c_str(), true) == -1) {
  498. throw std::system_error(errno, std::system_category());
  499. }
  500. }
  501. }
  502. }
  503. }
  504. // Get user confirmation before proceeding with restarting boot sequence.
  505. // Returns after confirmation, possibly with shutdown type altered.
  506. static void confirm_restart_boot() noexcept
  507. {
  508. // Bypass log; we want to make certain the message is seen:
  509. std::cout << "All services have stopped with no shutdown issued; boot failure?\n";
  510. // Drain input, set non-canonical input mode (receive characters as they are typed)
  511. struct termios term_attr;
  512. if (tcgetattr(STDIN_FILENO, &term_attr) != 0) {
  513. // Not a terminal?
  514. std::cout << "Halting." << std::endl;
  515. services->stop_all_services(shutdown_type_t::HALT);
  516. return;
  517. }
  518. term_attr.c_lflag &= ~ICANON;
  519. tcsetattr(STDIN_FILENO, TCSAFLUSH, &term_attr);
  520. // Set non-blocking mode
  521. int origFlags = fcntl(STDIN_FILENO, F_GETFL);
  522. fcntl(STDIN_FILENO, F_SETFL, origFlags | O_NONBLOCK);
  523. do_prompt:
  524. std::cout << "Choose: (r)eboot, r(e)covery, re(s)tart boot sequence, (p)ower off? " << std::flush;
  525. console_input_io.set_enabled(event_loop, true);
  526. do {
  527. event_loop.run();
  528. } while (! console_input_ready && services->get_shutdown_type() == shutdown_type_t::NONE);
  529. console_input_io.set_enabled(event_loop, false);
  530. // We either have input, or shutdown type has been set, or both.
  531. if (console_input_ready) {
  532. console_input_ready = false;
  533. char buf[1];
  534. int r = read(STDIN_FILENO, buf, 1); // read a single character, to make sure we wait for input
  535. if (r == 1) {
  536. std::cout << "\n"; // force new line after input
  537. if (buf[0] == 'r' || buf[0] == 'R') {
  538. services->stop_all_services(shutdown_type_t::REBOOT);
  539. }
  540. else if (buf[0] == 'e' || buf[0] == 'E') {
  541. try {
  542. services->start_service("recovery");
  543. }
  544. catch (...) {
  545. std::cout << "Unable to start recovery service.\n";
  546. goto do_prompt;
  547. }
  548. }
  549. else if (buf[0] == 's' || buf[0] == 'S') {
  550. // nothing - leave no shutdown type
  551. }
  552. else if (buf[0] == 'p' || buf[0] == 'P') {
  553. services->stop_all_services(shutdown_type_t::POWEROFF);
  554. }
  555. else {
  556. goto do_prompt;
  557. }
  558. }
  559. tcflush(STDIN_FILENO, TCIFLUSH); // discard the rest of input
  560. }
  561. term_attr.c_lflag |= ICANON;
  562. tcsetattr(STDIN_FILENO, TCSANOW, &term_attr);
  563. fcntl(STDIN_FILENO, F_SETFL, origFlags);
  564. }
  565. // Callback for control socket
  566. static void control_socket_cb(eventloop_t *loop, int sockfd)
  567. {
  568. // Considered keeping a limit the number of active connections, however, there doesn't
  569. // seem much to be gained from that. Only root can create connections and not being
  570. // able to establish a control connection is as much a denial-of-service as is not being
  571. // able to start a service due to lack of fd's.
  572. // Accept a connection
  573. int newfd = dinit_accept4(sockfd, nullptr, nullptr, SOCK_NONBLOCK | SOCK_CLOEXEC);
  574. if (newfd != -1) {
  575. try {
  576. new control_conn_t(*loop, services, newfd); // will delete itself when it's finished
  577. }
  578. catch (std::exception &exc) {
  579. log(loglevel_t::ERROR, "Accepting control connection: ", exc.what());
  580. close(newfd);
  581. }
  582. }
  583. }
  584. // Callback when the root filesystem is read/write:
  585. void rootfs_is_rw() noexcept
  586. {
  587. open_control_socket(true);
  588. if (! did_log_boot) {
  589. did_log_boot = log_boot();
  590. }
  591. }
  592. // Open/create the control socket, normally /dev/dinitctl, used to allow client programs to connect
  593. // and issue service orders and shutdown commands etc. This can safely be called multiple times;
  594. // once the socket has been successfully opened, further calls have no effect.
  595. static void open_control_socket(bool report_ro_failure) noexcept
  596. {
  597. if (control_socket_open) {
  598. struct stat stat_buf;
  599. if (stat(control_socket_path, &stat_buf) != 0 && errno == ENOENT) {
  600. // Looks like our control socket has disappeared from the filesystem. Close our control
  601. // socket and re-create it:
  602. control_socket_io.deregister(event_loop);
  603. close(control_socket_io.get_watched_fd());
  604. control_socket_open = false; // now re-open below
  605. }
  606. }
  607. if (! control_socket_open) {
  608. const char * saddrname = control_socket_path;
  609. size_t saddrname_len = strlen(saddrname);
  610. uint sockaddr_size = offsetof(struct sockaddr_un, sun_path) + saddrname_len + 1;
  611. struct sockaddr_un * name = static_cast<sockaddr_un *>(malloc(sockaddr_size));
  612. if (name == nullptr) {
  613. log(loglevel_t::ERROR, "Opening control socket: out of memory");
  614. return;
  615. }
  616. if (am_system_init) {
  617. // Unlink any stale control socket file, but only if we are system init, since otherwise
  618. // the 'stale' file may not be stale at all:
  619. unlink(saddrname);
  620. }
  621. name->sun_family = AF_UNIX;
  622. memcpy(name->sun_path, saddrname, saddrname_len + 1);
  623. int sockfd = dinit_socket(AF_UNIX, SOCK_STREAM, 0, SOCK_NONBLOCK | SOCK_CLOEXEC);
  624. if (sockfd == -1) {
  625. log(loglevel_t::ERROR, "Error creating control socket: ", strerror(errno));
  626. free(name);
  627. return;
  628. }
  629. if (bind(sockfd, (struct sockaddr *) name, sockaddr_size) == -1) {
  630. if (errno != EROFS || report_ro_failure) {
  631. log(loglevel_t::ERROR, "Error binding control socket: ", strerror(errno));
  632. }
  633. close(sockfd);
  634. free(name);
  635. return;
  636. }
  637. free(name);
  638. // No connections can be made until we listen, so it is fine to change the permissions now
  639. // (and anyway there is no way to atomically create the socket and set permissions):
  640. if (chmod(saddrname, S_IRUSR | S_IWUSR) == -1) {
  641. log(loglevel_t::ERROR, "Error setting control socket permissions: ", strerror(errno));
  642. close(sockfd);
  643. return;
  644. }
  645. if (listen(sockfd, 10) == -1) {
  646. log(loglevel_t::ERROR, "Error listening on control socket: ", strerror(errno));
  647. close(sockfd);
  648. return;
  649. }
  650. try {
  651. control_socket_io.add_watch(event_loop, sockfd, dasynq::IN_EVENTS);
  652. control_socket_open = true;
  653. }
  654. catch (std::exception &e)
  655. {
  656. log(loglevel_t::ERROR, "Could not setup I/O on control socket: ", e.what());
  657. close(sockfd);
  658. }
  659. }
  660. }
  661. static void close_control_socket() noexcept
  662. {
  663. if (control_socket_open) {
  664. int fd = control_socket_io.get_watched_fd();
  665. control_socket_io.deregister(event_loop);
  666. close(fd);
  667. // Unlink the socket:
  668. unlink(control_socket_path);
  669. control_socket_open = false;
  670. }
  671. }
  672. void setup_external_log() noexcept
  673. {
  674. if (! external_log_open) {
  675. if (log_is_syslog) {
  676. const char * saddrname = log_path;
  677. size_t saddrname_len = strlen(saddrname);
  678. uint sockaddr_size = offsetof(struct sockaddr_un, sun_path) + saddrname_len + 1;
  679. struct sockaddr_un * name = static_cast<sockaddr_un *>(malloc(sockaddr_size));
  680. if (name == nullptr) {
  681. log(loglevel_t::ERROR, "Connecting to log socket: out of memory");
  682. return;
  683. }
  684. name->sun_family = AF_UNIX;
  685. memcpy(name->sun_path, saddrname, saddrname_len + 1);
  686. int sockfd = dinit_socket(AF_UNIX, SOCK_DGRAM, 0, SOCK_NONBLOCK | SOCK_CLOEXEC);
  687. if (sockfd == -1) {
  688. log(loglevel_t::ERROR, "Error creating log socket: ", strerror(errno));
  689. free(name);
  690. return;
  691. }
  692. if (connect(sockfd, (struct sockaddr *) name, sockaddr_size) == 0 || errno == EINPROGRESS) {
  693. // For EINPROGRESS, connection is still being established; however, we can select on
  694. // the file descriptor so we will be notified when it's ready. In other words we can
  695. // basically use it anyway.
  696. try {
  697. setup_main_log(sockfd);
  698. external_log_open = true;
  699. }
  700. catch (std::exception &e) {
  701. log(loglevel_t::ERROR, "Setting up log failed: ", e.what());
  702. close(sockfd);
  703. }
  704. }
  705. else {
  706. // Note if connect fails, we haven't warned at all, because the syslog server might not
  707. // have started yet.
  708. close(sockfd);
  709. }
  710. free(name);
  711. }
  712. else {
  713. // log to file:
  714. int log_fd = open(log_path, O_WRONLY | O_CREAT | O_APPEND | O_NONBLOCK | O_CLOEXEC, 0644);
  715. if (log_fd >= 0) {
  716. try {
  717. setup_main_log(log_fd);
  718. external_log_open = true;
  719. }
  720. catch (std::exception &e) {
  721. log(loglevel_t::ERROR, "Setting up log failed: ", e.what());
  722. close(log_fd);
  723. }
  724. }
  725. else {
  726. // log failure to log? It makes more sense than first appears, because we also log
  727. // to console:
  728. log(loglevel_t::ERROR, "Setting up log failed: ", strerror(errno));
  729. }
  730. }
  731. }
  732. }
  733. /* handle SIGINT signal (generated by Linux kernel when ctrl+alt+del pressed) */
  734. static void sigint_reboot_cb(eventloop_t &eloop) noexcept
  735. {
  736. services->stop_all_services(shutdown_type_t::REBOOT);
  737. }
  738. /* handle SIGQUIT (if we are system init) */
  739. static void sigquit_cb(eventloop_t &eloop) noexcept
  740. {
  741. // This performs an immediate shutdown, without service rollback.
  742. close_control_socket();
  743. execl(shutdown_exec.c_str(), shutdown_exec.c_str(), "--system", (char *) 0);
  744. log(loglevel_t::ERROR, error_exec_sd, strerror(errno));
  745. sync(); // since a hard poweroff might be required at this point...
  746. }
  747. /* handle SIGTERM/SIGQUIT(non-system-daemon) - stop all services and shut down */
  748. static void sigterm_cb(eventloop_t &eloop) noexcept
  749. {
  750. services->stop_all_services();
  751. }