dinit.cc 35 KB

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