Line data Source code
1 : /*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
2 :
3 : /***
4 : This file is part of systemd.
5 :
6 : Copyright 2010 Lennart Poettering
7 :
8 : systemd is free software; you can redistribute it and/or modify it
9 : under the terms of the GNU Lesser General Public License as published by
10 : the Free Software Foundation; either version 2.1 of the License, or
11 : (at your option) any later version.
12 :
13 : systemd is distributed in the hope that it will be useful, but
14 : WITHOUT ANY WARRANTY; without even the implied warranty of
15 : MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 : Lesser General Public License for more details.
17 :
18 : You should have received a copy of the GNU Lesser General Public License
19 : along with systemd; If not, see <http://www.gnu.org/licenses/>.
20 : ***/
21 :
22 : #include <errno.h>
23 : #include <string.h>
24 : #include <signal.h>
25 : #include <sys/wait.h>
26 : #include <unistd.h>
27 : #include <sys/inotify.h>
28 : #include <sys/epoll.h>
29 : #include <sys/reboot.h>
30 : #include <sys/ioctl.h>
31 : #include <linux/kd.h>
32 : #include <fcntl.h>
33 : #include <dirent.h>
34 : #include <sys/timerfd.h>
35 :
36 : #ifdef HAVE_AUDIT
37 : #include <libaudit.h>
38 : #endif
39 :
40 : #include "sd-daemon.h"
41 : #include "sd-messages.h"
42 :
43 : #include "hashmap.h"
44 : #include "macro.h"
45 : #include "strv.h"
46 : #include "log.h"
47 : #include "util.h"
48 : #include "mkdir.h"
49 : #include "ratelimit.h"
50 : #include "locale-setup.h"
51 : #include "unit-name.h"
52 : #include "missing.h"
53 : #include "rm-rf.h"
54 : #include "path-lookup.h"
55 : #include "special.h"
56 : #include "exit-status.h"
57 : #include "virt.h"
58 : #include "watchdog.h"
59 : #include "path-util.h"
60 : #include "audit-fd.h"
61 : #include "boot-timestamps.h"
62 : #include "env-util.h"
63 : #include "bus-common-errors.h"
64 : #include "bus-error.h"
65 : #include "bus-util.h"
66 : #include "bus-kernel.h"
67 : #include "time-util.h"
68 : #include "process-util.h"
69 : #include "terminal-util.h"
70 : #include "signal-util.h"
71 : #include "dbus.h"
72 : #include "dbus-unit.h"
73 : #include "dbus-job.h"
74 : #include "dbus-manager.h"
75 : #include "manager.h"
76 : #include "transaction.h"
77 :
78 : /* Initial delay and the interval for printing status messages about running jobs */
79 : #define JOBS_IN_PROGRESS_WAIT_USEC (5*USEC_PER_SEC)
80 : #define JOBS_IN_PROGRESS_PERIOD_USEC (USEC_PER_SEC / 3)
81 : #define JOBS_IN_PROGRESS_PERIOD_DIVISOR 3
82 :
83 : static int manager_dispatch_notify_fd(sd_event_source *source, int fd, uint32_t revents, void *userdata);
84 : static int manager_dispatch_signal_fd(sd_event_source *source, int fd, uint32_t revents, void *userdata);
85 : static int manager_dispatch_time_change_fd(sd_event_source *source, int fd, uint32_t revents, void *userdata);
86 : static int manager_dispatch_idle_pipe_fd(sd_event_source *source, int fd, uint32_t revents, void *userdata);
87 : static int manager_dispatch_jobs_in_progress(sd_event_source *source, usec_t usec, void *userdata);
88 : static int manager_dispatch_run_queue(sd_event_source *source, void *userdata);
89 : static int manager_run_generators(Manager *m);
90 : static void manager_undo_generators(Manager *m);
91 :
92 6 : static void manager_watch_jobs_in_progress(Manager *m) {
93 : usec_t next;
94 : int r;
95 :
96 6 : assert(m);
97 :
98 6 : if (m->jobs_in_progress_event_source)
99 0 : return;
100 :
101 6 : next = now(CLOCK_MONOTONIC) + JOBS_IN_PROGRESS_WAIT_USEC;
102 6 : r = sd_event_add_time(
103 : m->event,
104 : &m->jobs_in_progress_event_source,
105 : CLOCK_MONOTONIC,
106 : next, 0,
107 : manager_dispatch_jobs_in_progress, m);
108 6 : if (r < 0)
109 0 : return;
110 :
111 6 : (void) sd_event_source_set_description(m->jobs_in_progress_event_source, "manager-jobs-in-progress");
112 : }
113 :
114 : #define CYLON_BUFFER_EXTRA (2*(sizeof(ANSI_RED_ON)-1) + sizeof(ANSI_HIGHLIGHT_RED_ON)-1 + 2*(sizeof(ANSI_HIGHLIGHT_OFF)-1))
115 :
116 0 : static void draw_cylon(char buffer[], size_t buflen, unsigned width, unsigned pos) {
117 0 : char *p = buffer;
118 :
119 0 : assert(buflen >= CYLON_BUFFER_EXTRA + width + 1);
120 0 : assert(pos <= width+1); /* 0 or width+1 mean that the center light is behind the corner */
121 :
122 0 : if (pos > 1) {
123 0 : if (pos > 2)
124 0 : p = mempset(p, ' ', pos-2);
125 0 : p = stpcpy(p, ANSI_RED_ON);
126 0 : *p++ = '*';
127 : }
128 :
129 0 : if (pos > 0 && pos <= width) {
130 0 : p = stpcpy(p, ANSI_HIGHLIGHT_RED_ON);
131 0 : *p++ = '*';
132 : }
133 :
134 0 : p = stpcpy(p, ANSI_HIGHLIGHT_OFF);
135 :
136 0 : if (pos < width) {
137 0 : p = stpcpy(p, ANSI_RED_ON);
138 0 : *p++ = '*';
139 0 : if (pos < width-1)
140 0 : p = mempset(p, ' ', width-1-pos);
141 0 : strcpy(p, ANSI_HIGHLIGHT_OFF);
142 : }
143 0 : }
144 :
145 0 : void manager_flip_auto_status(Manager *m, bool enable) {
146 0 : assert(m);
147 :
148 0 : if (enable) {
149 0 : if (m->show_status == SHOW_STATUS_AUTO)
150 0 : manager_set_show_status(m, SHOW_STATUS_TEMPORARY);
151 : } else {
152 0 : if (m->show_status == SHOW_STATUS_TEMPORARY)
153 0 : manager_set_show_status(m, SHOW_STATUS_AUTO);
154 : }
155 0 : }
156 :
157 0 : static void manager_print_jobs_in_progress(Manager *m) {
158 0 : _cleanup_free_ char *job_of_n = NULL;
159 : Iterator i;
160 : Job *j;
161 0 : unsigned counter = 0, print_nr;
162 : char cylon[6 + CYLON_BUFFER_EXTRA + 1];
163 : unsigned cylon_pos;
164 0 : char time[FORMAT_TIMESPAN_MAX], limit[FORMAT_TIMESPAN_MAX] = "no limit";
165 : uint64_t x;
166 :
167 0 : assert(m);
168 0 : assert(m->n_running_jobs > 0);
169 :
170 0 : manager_flip_auto_status(m, true);
171 :
172 0 : print_nr = (m->jobs_in_progress_iteration / JOBS_IN_PROGRESS_PERIOD_DIVISOR) % m->n_running_jobs;
173 :
174 0 : HASHMAP_FOREACH(j, m->jobs, i)
175 0 : if (j->state == JOB_RUNNING && counter++ == print_nr)
176 0 : break;
177 :
178 : /* m->n_running_jobs must be consistent with the contents of m->jobs,
179 : * so the above loop must have succeeded in finding j. */
180 0 : assert(counter == print_nr + 1);
181 0 : assert(j);
182 :
183 0 : cylon_pos = m->jobs_in_progress_iteration % 14;
184 0 : if (cylon_pos >= 8)
185 0 : cylon_pos = 14 - cylon_pos;
186 0 : draw_cylon(cylon, sizeof(cylon), 6, cylon_pos);
187 :
188 0 : m->jobs_in_progress_iteration++;
189 :
190 0 : if (m->n_running_jobs > 1) {
191 0 : if (asprintf(&job_of_n, "(%u of %u) ", counter, m->n_running_jobs) < 0)
192 0 : job_of_n = NULL;
193 : }
194 :
195 0 : format_timespan(time, sizeof(time), now(CLOCK_MONOTONIC) - j->begin_usec, 1*USEC_PER_SEC);
196 0 : if (job_get_timeout(j, &x) > 0)
197 0 : format_timespan(limit, sizeof(limit), x - j->begin_usec, 1*USEC_PER_SEC);
198 :
199 0 : manager_status_printf(m, STATUS_TYPE_EPHEMERAL, cylon,
200 : "%sA %s job is running for %s (%s / %s)",
201 : strempty(job_of_n),
202 0 : job_type_to_string(j->type),
203 0 : unit_description(j->unit),
204 : time, limit);
205 0 : }
206 :
207 0 : static int have_ask_password(void) {
208 0 : _cleanup_closedir_ DIR *dir;
209 :
210 0 : dir = opendir("/run/systemd/ask-password");
211 0 : if (!dir) {
212 0 : if (errno == ENOENT)
213 0 : return false;
214 : else
215 0 : return -errno;
216 : }
217 :
218 : for (;;) {
219 : struct dirent *de;
220 :
221 0 : errno = 0;
222 0 : de = readdir(dir);
223 0 : if (!de && errno != 0)
224 0 : return -errno;
225 0 : if (!de)
226 0 : return false;
227 :
228 0 : if (startswith(de->d_name, "ask."))
229 0 : return true;
230 0 : }
231 : }
232 :
233 0 : static int manager_dispatch_ask_password_fd(sd_event_source *source,
234 : int fd, uint32_t revents, void *userdata) {
235 0 : Manager *m = userdata;
236 :
237 0 : assert(m);
238 :
239 0 : flush_fd(fd);
240 :
241 0 : m->have_ask_password = have_ask_password();
242 0 : if (m->have_ask_password < 0)
243 : /* Log error but continue. Negative have_ask_password
244 : * is treated as unknown status. */
245 0 : log_error_errno(m->have_ask_password, "Failed to list /run/systemd/ask-password: %m");
246 :
247 0 : return 0;
248 : }
249 :
250 11 : static void manager_close_ask_password(Manager *m) {
251 11 : assert(m);
252 :
253 11 : m->ask_password_inotify_fd = safe_close(m->ask_password_inotify_fd);
254 11 : m->ask_password_event_source = sd_event_source_unref(m->ask_password_event_source);
255 11 : m->have_ask_password = -EINVAL;
256 11 : }
257 :
258 0 : static int manager_check_ask_password(Manager *m) {
259 : int r;
260 :
261 0 : assert(m);
262 :
263 0 : if (!m->ask_password_event_source) {
264 0 : assert(m->ask_password_inotify_fd < 0);
265 :
266 0 : mkdir_p_label("/run/systemd/ask-password", 0755);
267 :
268 0 : m->ask_password_inotify_fd = inotify_init1(IN_NONBLOCK|IN_CLOEXEC);
269 0 : if (m->ask_password_inotify_fd < 0)
270 0 : return log_error_errno(errno, "inotify_init1() failed: %m");
271 :
272 0 : if (inotify_add_watch(m->ask_password_inotify_fd, "/run/systemd/ask-password", IN_CREATE|IN_DELETE|IN_MOVE) < 0) {
273 0 : log_error_errno(errno, "Failed to add watch on /run/systemd/ask-password: %m");
274 0 : manager_close_ask_password(m);
275 0 : return -errno;
276 : }
277 :
278 0 : r = sd_event_add_io(m->event, &m->ask_password_event_source,
279 : m->ask_password_inotify_fd, EPOLLIN,
280 : manager_dispatch_ask_password_fd, m);
281 0 : if (r < 0) {
282 0 : log_error_errno(errno, "Failed to add event source for /run/systemd/ask-password: %m");
283 0 : manager_close_ask_password(m);
284 0 : return -errno;
285 : }
286 :
287 0 : (void) sd_event_source_set_description(m->ask_password_event_source, "manager-ask-password");
288 :
289 : /* Queries might have been added meanwhile... */
290 0 : manager_dispatch_ask_password_fd(m->ask_password_event_source,
291 : m->ask_password_inotify_fd, EPOLLIN, m);
292 : }
293 :
294 0 : return m->have_ask_password;
295 : }
296 :
297 0 : static int manager_watch_idle_pipe(Manager *m) {
298 : int r;
299 :
300 0 : assert(m);
301 :
302 0 : if (m->idle_pipe_event_source)
303 0 : return 0;
304 :
305 0 : if (m->idle_pipe[2] < 0)
306 0 : return 0;
307 :
308 0 : r = sd_event_add_io(m->event, &m->idle_pipe_event_source, m->idle_pipe[2], EPOLLIN, manager_dispatch_idle_pipe_fd, m);
309 0 : if (r < 0)
310 0 : return log_error_errno(r, "Failed to watch idle pipe: %m");
311 :
312 0 : (void) sd_event_source_set_description(m->idle_pipe_event_source, "manager-idle-pipe");
313 :
314 0 : return 0;
315 : }
316 :
317 11 : static void manager_close_idle_pipe(Manager *m) {
318 11 : assert(m);
319 :
320 11 : safe_close_pair(m->idle_pipe);
321 11 : safe_close_pair(m->idle_pipe + 2);
322 11 : }
323 :
324 11 : static int manager_setup_time_change(Manager *m) {
325 : int r;
326 :
327 : /* We only care for the cancellation event, hence we set the
328 : * timeout to the latest possible value. */
329 11 : struct itimerspec its = {
330 : .it_value.tv_sec = TIME_T_MAX,
331 : };
332 :
333 11 : assert(m);
334 : assert_cc(sizeof(time_t) == sizeof(TIME_T_MAX));
335 :
336 11 : if (m->test_run)
337 11 : return 0;
338 :
339 : /* Uses TFD_TIMER_CANCEL_ON_SET to get notifications whenever
340 : * CLOCK_REALTIME makes a jump relative to CLOCK_MONOTONIC */
341 :
342 0 : m->time_change_fd = timerfd_create(CLOCK_REALTIME, TFD_NONBLOCK|TFD_CLOEXEC);
343 0 : if (m->time_change_fd < 0)
344 0 : return log_error_errno(errno, "Failed to create timerfd: %m");
345 :
346 0 : if (timerfd_settime(m->time_change_fd, TFD_TIMER_ABSTIME|TFD_TIMER_CANCEL_ON_SET, &its, NULL) < 0) {
347 0 : log_debug_errno(errno, "Failed to set up TFD_TIMER_CANCEL_ON_SET, ignoring: %m");
348 0 : m->time_change_fd = safe_close(m->time_change_fd);
349 0 : return 0;
350 : }
351 :
352 0 : r = sd_event_add_io(m->event, &m->time_change_event_source, m->time_change_fd, EPOLLIN, manager_dispatch_time_change_fd, m);
353 0 : if (r < 0)
354 0 : return log_error_errno(r, "Failed to create time change event source: %m");
355 :
356 0 : (void) sd_event_source_set_description(m->time_change_event_source, "manager-time-change");
357 :
358 0 : log_debug("Set up TFD_TIMER_CANCEL_ON_SET timerfd.");
359 :
360 0 : return 0;
361 : }
362 :
363 0 : static int enable_special_signals(Manager *m) {
364 0 : _cleanup_close_ int fd = -1;
365 :
366 0 : assert(m);
367 :
368 : /* Enable that we get SIGINT on control-alt-del. In containers
369 : * this will fail with EPERM (older) or EINVAL (newer), so
370 : * ignore that. */
371 0 : if (reboot(RB_DISABLE_CAD) < 0 && errno != EPERM && errno != EINVAL)
372 0 : log_warning_errno(errno, "Failed to enable ctrl-alt-del handling: %m");
373 :
374 0 : fd = open_terminal("/dev/tty0", O_RDWR|O_NOCTTY|O_CLOEXEC);
375 0 : if (fd < 0) {
376 : /* Support systems without virtual console */
377 0 : if (fd != -ENOENT)
378 0 : log_warning_errno(errno, "Failed to open /dev/tty0: %m");
379 : } else {
380 : /* Enable that we get SIGWINCH on kbrequest */
381 0 : if (ioctl(fd, KDSIGACCEPT, SIGWINCH) < 0)
382 0 : log_warning_errno(errno, "Failed to enable kbrequest handling: %m");
383 : }
384 :
385 0 : return 0;
386 : }
387 :
388 11 : static int manager_setup_signals(Manager *m) {
389 11 : struct sigaction sa = {
390 : .sa_handler = SIG_DFL,
391 : .sa_flags = SA_NOCLDSTOP|SA_RESTART,
392 : };
393 : sigset_t mask;
394 : int r;
395 :
396 11 : assert(m);
397 :
398 11 : assert_se(sigaction(SIGCHLD, &sa, NULL) == 0);
399 :
400 : /* We make liberal use of realtime signals here. On
401 : * Linux/glibc we have 30 of them (with the exception of Linux
402 : * on hppa, see below), between SIGRTMIN+0 ... SIGRTMIN+30
403 : * (aka SIGRTMAX). */
404 :
405 11 : assert_se(sigemptyset(&mask) == 0);
406 209 : sigset_add_many(&mask,
407 : SIGCHLD, /* Child died */
408 : SIGTERM, /* Reexecute daemon */
409 : SIGHUP, /* Reload configuration */
410 : SIGUSR1, /* systemd/upstart: reconnect to D-Bus */
411 : SIGUSR2, /* systemd: dump status */
412 : SIGINT, /* Kernel sends us this on control-alt-del */
413 : SIGWINCH, /* Kernel sends us this on kbrequest (alt-arrowup) */
414 : SIGPWR, /* Some kernel drivers and upsd send us this on power failure */
415 :
416 : SIGRTMIN+0, /* systemd: start default.target */
417 11 : SIGRTMIN+1, /* systemd: isolate rescue.target */
418 11 : SIGRTMIN+2, /* systemd: isolate emergency.target */
419 11 : SIGRTMIN+3, /* systemd: start halt.target */
420 11 : SIGRTMIN+4, /* systemd: start poweroff.target */
421 11 : SIGRTMIN+5, /* systemd: start reboot.target */
422 11 : SIGRTMIN+6, /* systemd: start kexec.target */
423 :
424 : /* ... space for more special targets ... */
425 :
426 11 : SIGRTMIN+13, /* systemd: Immediate halt */
427 11 : SIGRTMIN+14, /* systemd: Immediate poweroff */
428 11 : SIGRTMIN+15, /* systemd: Immediate reboot */
429 11 : SIGRTMIN+16, /* systemd: Immediate kexec */
430 :
431 : /* ... space for more immediate system state changes ... */
432 :
433 11 : SIGRTMIN+20, /* systemd: enable status messages */
434 11 : SIGRTMIN+21, /* systemd: disable status messages */
435 11 : SIGRTMIN+22, /* systemd: set log level to LOG_DEBUG */
436 11 : SIGRTMIN+23, /* systemd: set log level to LOG_INFO */
437 11 : SIGRTMIN+24, /* systemd: Immediate exit (--user only) */
438 :
439 : /* .. one free signal here ... */
440 :
441 : #if !defined(__hppa64__) && !defined(__hppa__)
442 : /* Apparently Linux on hppa has fewer RT
443 : * signals (SIGRTMAX is SIGRTMIN+25 there),
444 : * hence let's not try to make use of them
445 : * here. Since these commands are accessible
446 : * by different means and only really a safety
447 : * net, the missing functionality on hppa
448 : * shouldn't matter. */
449 :
450 11 : SIGRTMIN+26, /* systemd: set log target to journal-or-kmsg */
451 11 : SIGRTMIN+27, /* systemd: set log target to console */
452 11 : SIGRTMIN+28, /* systemd: set log target to kmsg */
453 11 : SIGRTMIN+29, /* systemd: set log target to syslog-or-kmsg (obsolete) */
454 :
455 : /* ... one free signal here SIGRTMIN+30 ... */
456 : #endif
457 : -1);
458 11 : assert_se(sigprocmask(SIG_SETMASK, &mask, NULL) == 0);
459 :
460 11 : m->signal_fd = signalfd(-1, &mask, SFD_NONBLOCK|SFD_CLOEXEC);
461 11 : if (m->signal_fd < 0)
462 0 : return -errno;
463 :
464 11 : r = sd_event_add_io(m->event, &m->signal_event_source, m->signal_fd, EPOLLIN, manager_dispatch_signal_fd, m);
465 11 : if (r < 0)
466 0 : return r;
467 :
468 11 : (void) sd_event_source_set_description(m->signal_event_source, "manager-signal");
469 :
470 : /* Process signals a bit earlier than the rest of things, but
471 : * later than notify_fd processing, so that the notify
472 : * processing can still figure out to which process/service a
473 : * message belongs, before we reap the process. */
474 11 : r = sd_event_source_set_priority(m->signal_event_source, -5);
475 11 : if (r < 0)
476 0 : return r;
477 :
478 11 : if (m->running_as == MANAGER_SYSTEM)
479 0 : return enable_special_signals(m);
480 :
481 11 : return 0;
482 : }
483 :
484 11 : static void manager_clean_environment(Manager *m) {
485 11 : assert(m);
486 :
487 : /* Let's remove some environment variables that we
488 : * need ourselves to communicate with our clients */
489 11 : strv_env_unset_many(
490 : m->environment,
491 : "NOTIFY_SOCKET",
492 : "MAINPID",
493 : "MANAGERPID",
494 : "LISTEN_PID",
495 : "LISTEN_FDS",
496 : "WATCHDOG_PID",
497 : "WATCHDOG_USEC",
498 : NULL);
499 11 : }
500 :
501 11 : static int manager_default_environment(Manager *m) {
502 11 : assert(m);
503 :
504 11 : if (m->running_as == MANAGER_SYSTEM) {
505 : /* The system manager always starts with a clean
506 : * environment for its children. It does not import
507 : * the kernel or the parents exported variables.
508 : *
509 : * The initial passed environ is untouched to keep
510 : * /proc/self/environ valid; it is used for tagging
511 : * the init process inside containers. */
512 0 : m->environment = strv_new("PATH=" DEFAULT_PATH,
513 : NULL);
514 :
515 : /* Import locale variables LC_*= from configuration */
516 0 : locale_setup(&m->environment);
517 : } else {
518 : /* The user manager passes its own environment
519 : * along to its children. */
520 11 : m->environment = strv_copy(environ);
521 : }
522 :
523 11 : if (!m->environment)
524 0 : return -ENOMEM;
525 :
526 11 : manager_clean_environment(m);
527 11 : strv_sort(m->environment);
528 :
529 11 : return 0;
530 : }
531 :
532 :
533 11 : int manager_new(ManagerRunningAs running_as, bool test_run, Manager **_m) {
534 :
535 : static const char * const unit_log_fields[_MANAGER_RUNNING_AS_MAX] = {
536 : [MANAGER_SYSTEM] = "UNIT=",
537 : [MANAGER_USER] = "USER_UNIT=",
538 : };
539 :
540 : static const char * const unit_log_format_strings[_MANAGER_RUNNING_AS_MAX] = {
541 : [MANAGER_SYSTEM] = "UNIT=%s",
542 : [MANAGER_USER] = "USER_UNIT=%s",
543 : };
544 :
545 : Manager *m;
546 : int r;
547 :
548 11 : assert(_m);
549 11 : assert(running_as >= 0);
550 11 : assert(running_as < _MANAGER_RUNNING_AS_MAX);
551 :
552 11 : m = new0(Manager, 1);
553 11 : if (!m)
554 0 : return -ENOMEM;
555 :
556 : #ifdef ENABLE_EFI
557 11 : if (running_as == MANAGER_SYSTEM && detect_container(NULL) <= 0)
558 0 : boot_timestamps(&m->userspace_timestamp, &m->firmware_timestamp, &m->loader_timestamp);
559 : #endif
560 :
561 11 : m->running_as = running_as;
562 11 : m->exit_code = _MANAGER_EXIT_CODE_INVALID;
563 11 : m->default_timer_accuracy_usec = USEC_PER_MINUTE;
564 :
565 : /* Prepare log fields we can use for structured logging */
566 11 : m->unit_log_field = unit_log_fields[running_as];
567 11 : m->unit_log_format_string = unit_log_format_strings[running_as];
568 :
569 11 : m->idle_pipe[0] = m->idle_pipe[1] = m->idle_pipe[2] = m->idle_pipe[3] = -1;
570 :
571 11 : m->pin_cgroupfs_fd = m->notify_fd = m->signal_fd = m->time_change_fd = m->dev_autofs_fd = m->private_listen_fd = m->kdbus_fd = m->utab_inotify_fd = -1;
572 11 : m->current_job_id = 1; /* start as id #1, so that we can leave #0 around as "null-like" value */
573 :
574 11 : m->ask_password_inotify_fd = -1;
575 11 : m->have_ask_password = -EINVAL; /* we don't know */
576 :
577 11 : m->test_run = test_run;
578 :
579 : /* Reboot immediately if the user hits C-A-D more often than 7x per 2s */
580 11 : RATELIMIT_INIT(m->ctrl_alt_del_ratelimit, 2 * USEC_PER_SEC, 7);
581 :
582 11 : r = manager_default_environment(m);
583 11 : if (r < 0)
584 0 : goto fail;
585 :
586 11 : r = hashmap_ensure_allocated(&m->units, &string_hash_ops);
587 11 : if (r < 0)
588 0 : goto fail;
589 :
590 11 : r = hashmap_ensure_allocated(&m->jobs, NULL);
591 11 : if (r < 0)
592 0 : goto fail;
593 :
594 11 : r = hashmap_ensure_allocated(&m->cgroup_unit, &string_hash_ops);
595 11 : if (r < 0)
596 0 : goto fail;
597 :
598 11 : r = hashmap_ensure_allocated(&m->watch_bus, &string_hash_ops);
599 11 : if (r < 0)
600 0 : goto fail;
601 :
602 11 : r = set_ensure_allocated(&m->startup_units, NULL);
603 11 : if (r < 0)
604 0 : goto fail;
605 :
606 11 : r = set_ensure_allocated(&m->failed_units, NULL);
607 11 : if (r < 0)
608 0 : goto fail;
609 :
610 11 : r = sd_event_default(&m->event);
611 11 : if (r < 0)
612 0 : goto fail;
613 :
614 11 : r = sd_event_add_defer(m->event, &m->run_queue_event_source, manager_dispatch_run_queue, m);
615 11 : if (r < 0)
616 0 : goto fail;
617 :
618 11 : r = sd_event_source_set_priority(m->run_queue_event_source, SD_EVENT_PRIORITY_IDLE);
619 11 : if (r < 0)
620 0 : goto fail;
621 :
622 11 : r = sd_event_source_set_enabled(m->run_queue_event_source, SD_EVENT_OFF);
623 11 : if (r < 0)
624 0 : goto fail;
625 :
626 11 : (void) sd_event_source_set_description(m->run_queue_event_source, "manager-run-queue");
627 :
628 11 : r = manager_setup_signals(m);
629 11 : if (r < 0)
630 0 : goto fail;
631 :
632 11 : r = manager_setup_cgroup(m);
633 11 : if (r < 0)
634 0 : goto fail;
635 :
636 11 : r = manager_setup_time_change(m);
637 11 : if (r < 0)
638 0 : goto fail;
639 :
640 11 : m->udev = udev_new();
641 11 : if (!m->udev) {
642 0 : r = -ENOMEM;
643 0 : goto fail;
644 : }
645 :
646 : /* Note that we set up neither kdbus, nor the notify fd
647 : * here. We do that after deserialization, since they might
648 : * have gotten serialized across the reexec. */
649 :
650 11 : m->taint_usr = dir_is_empty("/usr") > 0;
651 :
652 11 : *_m = m;
653 11 : return 0;
654 :
655 : fail:
656 0 : manager_free(m);
657 0 : return r;
658 : }
659 :
660 10 : static int manager_setup_notify(Manager *m) {
661 : int r;
662 :
663 10 : if (m->test_run)
664 10 : return 0;
665 :
666 0 : if (m->notify_fd < 0) {
667 0 : _cleanup_close_ int fd = -1;
668 0 : union sockaddr_union sa = {
669 : .sa.sa_family = AF_UNIX,
670 : };
671 : static const int one = 1;
672 :
673 : /* First free all secondary fields */
674 0 : free(m->notify_socket);
675 0 : m->notify_socket = NULL;
676 0 : m->notify_event_source = sd_event_source_unref(m->notify_event_source);
677 :
678 0 : fd = socket(AF_UNIX, SOCK_DGRAM|SOCK_CLOEXEC|SOCK_NONBLOCK, 0);
679 0 : if (fd < 0)
680 0 : return log_error_errno(errno, "Failed to allocate notification socket: %m");
681 :
682 0 : if (m->running_as == MANAGER_SYSTEM)
683 0 : m->notify_socket = strdup("/run/systemd/notify");
684 : else {
685 : const char *e;
686 :
687 0 : e = getenv("XDG_RUNTIME_DIR");
688 0 : if (!e) {
689 0 : log_error_errno(errno, "XDG_RUNTIME_DIR is not set: %m");
690 0 : return -EINVAL;
691 : }
692 :
693 0 : m->notify_socket = strappend(e, "/systemd/notify");
694 : }
695 0 : if (!m->notify_socket)
696 0 : return log_oom();
697 :
698 0 : (void) mkdir_parents_label(m->notify_socket, 0755);
699 0 : (void) unlink(m->notify_socket);
700 :
701 0 : strncpy(sa.un.sun_path, m->notify_socket, sizeof(sa.un.sun_path)-1);
702 0 : r = bind(fd, &sa.sa, offsetof(struct sockaddr_un, sun_path) + strlen(sa.un.sun_path));
703 0 : if (r < 0)
704 0 : return log_error_errno(errno, "bind(%s) failed: %m", sa.un.sun_path);
705 :
706 0 : r = setsockopt(fd, SOL_SOCKET, SO_PASSCRED, &one, sizeof(one));
707 0 : if (r < 0)
708 0 : return log_error_errno(errno, "SO_PASSCRED failed: %m");
709 :
710 0 : m->notify_fd = fd;
711 0 : fd = -1;
712 :
713 0 : log_debug("Using notification socket %s", m->notify_socket);
714 : }
715 :
716 0 : if (!m->notify_event_source) {
717 0 : r = sd_event_add_io(m->event, &m->notify_event_source, m->notify_fd, EPOLLIN, manager_dispatch_notify_fd, m);
718 0 : if (r < 0)
719 0 : return log_error_errno(r, "Failed to allocate notify event source: %m");
720 :
721 : /* Process signals a bit earlier than SIGCHLD, so that we can
722 : * still identify to which service an exit message belongs */
723 0 : r = sd_event_source_set_priority(m->notify_event_source, -7);
724 0 : if (r < 0)
725 0 : return log_error_errno(r, "Failed to set priority of notify event source: %m");
726 :
727 0 : (void) sd_event_source_set_description(m->notify_event_source, "manager-notify");
728 : }
729 :
730 0 : return 0;
731 : }
732 :
733 10 : static int manager_setup_kdbus(Manager *m) {
734 20 : _cleanup_free_ char *p = NULL;
735 :
736 10 : assert(m);
737 :
738 10 : if (m->test_run || m->kdbus_fd >= 0)
739 10 : return 0;
740 0 : if (!is_kdbus_available())
741 0 : return -ESOCKTNOSUPPORT;
742 :
743 0 : m->kdbus_fd = bus_kernel_create_bus(
744 0 : m->running_as == MANAGER_SYSTEM ? "system" : "user",
745 0 : m->running_as == MANAGER_SYSTEM, &p);
746 :
747 0 : if (m->kdbus_fd < 0)
748 0 : return log_debug_errno(m->kdbus_fd, "Failed to set up kdbus: %m");
749 :
750 0 : log_debug("Successfully set up kdbus on %s", p);
751 :
752 0 : return 0;
753 : }
754 :
755 10 : static int manager_connect_bus(Manager *m, bool reexecuting) {
756 : bool try_bus_connect;
757 :
758 10 : assert(m);
759 :
760 10 : if (m->test_run)
761 10 : return 0;
762 :
763 0 : try_bus_connect =
764 0 : m->kdbus_fd >= 0 ||
765 0 : reexecuting ||
766 0 : (m->running_as == MANAGER_USER && getenv("DBUS_SESSION_BUS_ADDRESS"));
767 :
768 : /* Try to connect to the buses, if possible. */
769 0 : return bus_init(m, try_bus_connect);
770 : }
771 :
772 11 : static unsigned manager_dispatch_cleanup_queue(Manager *m) {
773 : Unit *u;
774 11 : unsigned n = 0;
775 :
776 11 : assert(m);
777 :
778 22 : while ((u = m->cleanup_queue)) {
779 0 : assert(u->in_cleanup_queue);
780 :
781 0 : unit_free(u);
782 0 : n++;
783 : }
784 :
785 11 : return n;
786 : }
787 :
788 : enum {
789 : GC_OFFSET_IN_PATH, /* This one is on the path we were traveling */
790 : GC_OFFSET_UNSURE, /* No clue */
791 : GC_OFFSET_GOOD, /* We still need this unit */
792 : GC_OFFSET_BAD, /* We don't need this unit anymore */
793 : _GC_OFFSET_MAX
794 : };
795 :
796 0 : static void unit_gc_sweep(Unit *u, unsigned gc_marker) {
797 : Iterator i;
798 : Unit *other;
799 : bool is_bad;
800 :
801 0 : assert(u);
802 :
803 0 : if (u->gc_marker == gc_marker + GC_OFFSET_GOOD ||
804 0 : u->gc_marker == gc_marker + GC_OFFSET_BAD ||
805 0 : u->gc_marker == gc_marker + GC_OFFSET_IN_PATH)
806 0 : return;
807 :
808 0 : if (u->in_cleanup_queue)
809 0 : goto bad;
810 :
811 0 : if (unit_check_gc(u))
812 0 : goto good;
813 :
814 0 : u->gc_marker = gc_marker + GC_OFFSET_IN_PATH;
815 :
816 0 : is_bad = true;
817 :
818 0 : SET_FOREACH(other, u->dependencies[UNIT_REFERENCED_BY], i) {
819 0 : unit_gc_sweep(other, gc_marker);
820 :
821 0 : if (other->gc_marker == gc_marker + GC_OFFSET_GOOD)
822 0 : goto good;
823 :
824 0 : if (other->gc_marker != gc_marker + GC_OFFSET_BAD)
825 0 : is_bad = false;
826 : }
827 :
828 0 : if (is_bad)
829 0 : goto bad;
830 :
831 : /* We were unable to find anything out about this entry, so
832 : * let's investigate it later */
833 0 : u->gc_marker = gc_marker + GC_OFFSET_UNSURE;
834 0 : unit_add_to_gc_queue(u);
835 0 : return;
836 :
837 : bad:
838 : /* We definitely know that this one is not useful anymore, so
839 : * let's mark it for deletion */
840 0 : u->gc_marker = gc_marker + GC_OFFSET_BAD;
841 0 : unit_add_to_cleanup_queue(u);
842 0 : return;
843 :
844 : good:
845 0 : u->gc_marker = gc_marker + GC_OFFSET_GOOD;
846 : }
847 :
848 0 : static unsigned manager_dispatch_gc_queue(Manager *m) {
849 : Unit *u;
850 0 : unsigned n = 0;
851 : unsigned gc_marker;
852 :
853 0 : assert(m);
854 :
855 : /* log_debug("Running GC..."); */
856 :
857 0 : m->gc_marker += _GC_OFFSET_MAX;
858 0 : if (m->gc_marker + _GC_OFFSET_MAX <= _GC_OFFSET_MAX)
859 0 : m->gc_marker = 1;
860 :
861 0 : gc_marker = m->gc_marker;
862 :
863 0 : while ((u = m->gc_queue)) {
864 0 : assert(u->in_gc_queue);
865 :
866 0 : unit_gc_sweep(u, gc_marker);
867 :
868 0 : LIST_REMOVE(gc_queue, m->gc_queue, u);
869 0 : u->in_gc_queue = false;
870 :
871 0 : n++;
872 :
873 0 : if (u->gc_marker == gc_marker + GC_OFFSET_BAD ||
874 0 : u->gc_marker == gc_marker + GC_OFFSET_UNSURE) {
875 0 : if (u->id)
876 0 : log_unit_debug(u, "Collecting.");
877 0 : u->gc_marker = gc_marker + GC_OFFSET_BAD;
878 0 : unit_add_to_cleanup_queue(u);
879 : }
880 : }
881 :
882 0 : m->n_in_gc_queue = 0;
883 :
884 0 : return n;
885 : }
886 :
887 11 : static void manager_clear_jobs_and_units(Manager *m) {
888 : Unit *u;
889 :
890 11 : assert(m);
891 :
892 806 : while ((u = hashmap_first(m->units)))
893 784 : unit_free(u);
894 :
895 11 : manager_dispatch_cleanup_queue(m);
896 :
897 11 : assert(!m->load_queue);
898 11 : assert(!m->run_queue);
899 11 : assert(!m->dbus_unit_queue);
900 11 : assert(!m->dbus_job_queue);
901 11 : assert(!m->cleanup_queue);
902 11 : assert(!m->gc_queue);
903 :
904 11 : assert(hashmap_isempty(m->jobs));
905 11 : assert(hashmap_isempty(m->units));
906 :
907 11 : m->n_on_console = 0;
908 11 : m->n_running_jobs = 0;
909 11 : }
910 :
911 11 : Manager* manager_free(Manager *m) {
912 : UnitType c;
913 : int i;
914 :
915 11 : if (!m)
916 0 : return NULL;
917 :
918 11 : manager_clear_jobs_and_units(m);
919 :
920 154 : for (c = 0; c < _UNIT_TYPE_MAX; c++)
921 143 : if (unit_vtable[c]->shutdown)
922 44 : unit_vtable[c]->shutdown(m);
923 :
924 : /* If we reexecute ourselves, we keep the root cgroup
925 : * around */
926 11 : manager_shutdown_cgroup(m, m->exit_code != MANAGER_REEXECUTE);
927 :
928 11 : manager_undo_generators(m);
929 :
930 11 : bus_done(m);
931 :
932 11 : hashmap_free(m->units);
933 11 : hashmap_free(m->jobs);
934 11 : hashmap_free(m->watch_pids1);
935 11 : hashmap_free(m->watch_pids2);
936 11 : hashmap_free(m->watch_bus);
937 :
938 11 : set_free(m->startup_units);
939 11 : set_free(m->failed_units);
940 :
941 11 : sd_event_source_unref(m->signal_event_source);
942 11 : sd_event_source_unref(m->notify_event_source);
943 11 : sd_event_source_unref(m->time_change_event_source);
944 11 : sd_event_source_unref(m->jobs_in_progress_event_source);
945 11 : sd_event_source_unref(m->idle_pipe_event_source);
946 11 : sd_event_source_unref(m->run_queue_event_source);
947 :
948 11 : safe_close(m->signal_fd);
949 11 : safe_close(m->notify_fd);
950 11 : safe_close(m->time_change_fd);
951 11 : safe_close(m->kdbus_fd);
952 :
953 11 : manager_close_ask_password(m);
954 :
955 11 : manager_close_idle_pipe(m);
956 :
957 11 : udev_unref(m->udev);
958 11 : sd_event_unref(m->event);
959 :
960 11 : free(m->notify_socket);
961 :
962 11 : lookup_paths_free(&m->lookup_paths);
963 11 : strv_free(m->environment);
964 :
965 11 : hashmap_free(m->cgroup_unit);
966 11 : set_free_free(m->unit_path_cache);
967 :
968 11 : free(m->switch_root);
969 11 : free(m->switch_root_init);
970 :
971 187 : for (i = 0; i < _RLIMIT_MAX; i++)
972 176 : free(m->rlimit[i]);
973 :
974 11 : assert(hashmap_isempty(m->units_requiring_mounts_for));
975 11 : hashmap_free(m->units_requiring_mounts_for);
976 :
977 11 : free(m);
978 11 : return NULL;
979 : }
980 :
981 10 : int manager_enumerate(Manager *m) {
982 10 : int r = 0;
983 : UnitType c;
984 :
985 10 : assert(m);
986 :
987 : /* Let's ask every type to load all units from disk/kernel
988 : * that it might know */
989 140 : for (c = 0; c < _UNIT_TYPE_MAX; c++) {
990 : int q;
991 :
992 130 : if (!unit_type_supported(c)) {
993 0 : log_debug("Unit type .%s is not supported on this system.", unit_type_to_string(c));
994 0 : continue;
995 : }
996 :
997 130 : if (!unit_vtable[c]->enumerate)
998 100 : continue;
999 :
1000 30 : q = unit_vtable[c]->enumerate(m);
1001 30 : if (q < 0)
1002 0 : r = q;
1003 : }
1004 :
1005 10 : manager_dispatch_load_queue(m);
1006 10 : return r;
1007 : }
1008 :
1009 10 : static void manager_coldplug(Manager *m) {
1010 : Iterator i;
1011 : Unit *u;
1012 : char *k;
1013 : int r;
1014 :
1015 10 : assert(m);
1016 :
1017 : /* Then, let's set up their initial state. */
1018 670 : HASHMAP_FOREACH_KEY(u, k, m->units, i) {
1019 :
1020 : /* ignore aliases */
1021 650 : if (u->id != k)
1022 0 : continue;
1023 :
1024 650 : r = unit_coldplug(u);
1025 650 : if (r < 0)
1026 0 : log_warning_errno(r, "We couldn't coldplug %s, proceeding anyway: %m", u->id);
1027 : }
1028 10 : }
1029 :
1030 10 : static void manager_build_unit_path_cache(Manager *m) {
1031 : char **i;
1032 20 : _cleanup_closedir_ DIR *d = NULL;
1033 : int r;
1034 :
1035 10 : assert(m);
1036 :
1037 10 : set_free_free(m->unit_path_cache);
1038 :
1039 10 : m->unit_path_cache = set_new(&string_hash_ops);
1040 10 : if (!m->unit_path_cache) {
1041 0 : log_error("Failed to allocate unit path cache.");
1042 0 : return;
1043 : }
1044 :
1045 : /* This simply builds a list of files we know exist, so that
1046 : * we don't always have to go to disk */
1047 :
1048 20 : STRV_FOREACH(i, m->lookup_paths.unit_path) {
1049 : struct dirent *de;
1050 :
1051 10 : d = opendir(*i);
1052 10 : if (!d) {
1053 0 : if (errno != ENOENT)
1054 0 : log_error_errno(errno, "Failed to open directory %s: %m", *i);
1055 0 : continue;
1056 : }
1057 :
1058 910 : while ((de = readdir(d))) {
1059 : char *p;
1060 :
1061 890 : if (hidden_file(de->d_name))
1062 30 : continue;
1063 :
1064 860 : p = strjoin(streq(*i, "/") ? "" : *i, "/", de->d_name, NULL);
1065 860 : if (!p) {
1066 0 : r = -ENOMEM;
1067 0 : goto fail;
1068 : }
1069 :
1070 860 : r = set_consume(m->unit_path_cache, p);
1071 860 : if (r < 0)
1072 0 : goto fail;
1073 : }
1074 :
1075 10 : closedir(d);
1076 10 : d = NULL;
1077 : }
1078 :
1079 10 : return;
1080 :
1081 : fail:
1082 0 : log_error_errno(r, "Failed to build unit path cache: %m");
1083 :
1084 0 : set_free_free(m->unit_path_cache);
1085 0 : m->unit_path_cache = NULL;
1086 : }
1087 :
1088 :
1089 0 : static int manager_distribute_fds(Manager *m, FDSet *fds) {
1090 : Unit *u;
1091 : Iterator i;
1092 : int r;
1093 :
1094 0 : assert(m);
1095 :
1096 0 : HASHMAP_FOREACH(u, m->units, i) {
1097 :
1098 0 : if (fdset_size(fds) <= 0)
1099 0 : break;
1100 :
1101 0 : if (UNIT_VTABLE(u)->distribute_fds) {
1102 0 : r = UNIT_VTABLE(u)->distribute_fds(u, fds);
1103 0 : if (r < 0)
1104 0 : return r;
1105 : }
1106 : }
1107 :
1108 0 : return 0;
1109 : }
1110 :
1111 10 : int manager_startup(Manager *m, FILE *serialization, FDSet *fds) {
1112 : int r, q;
1113 :
1114 10 : assert(m);
1115 :
1116 10 : dual_timestamp_get(&m->generators_start_timestamp);
1117 10 : r = manager_run_generators(m);
1118 10 : dual_timestamp_get(&m->generators_finish_timestamp);
1119 10 : if (r < 0)
1120 0 : return r;
1121 :
1122 10 : r = lookup_paths_init(
1123 : &m->lookup_paths, m->running_as, true,
1124 : NULL,
1125 10 : m->generator_unit_path,
1126 10 : m->generator_unit_path_early,
1127 10 : m->generator_unit_path_late);
1128 10 : if (r < 0)
1129 0 : return r;
1130 :
1131 10 : manager_build_unit_path_cache(m);
1132 :
1133 : /* If we will deserialize make sure that during enumeration
1134 : * this is already known, so we increase the counter here
1135 : * already */
1136 10 : if (serialization)
1137 0 : m->n_reloading ++;
1138 :
1139 : /* First, enumerate what we can from all config files */
1140 10 : dual_timestamp_get(&m->units_load_start_timestamp);
1141 10 : r = manager_enumerate(m);
1142 10 : dual_timestamp_get(&m->units_load_finish_timestamp);
1143 :
1144 : /* Second, deserialize if there is something to deserialize */
1145 10 : if (serialization)
1146 0 : r = manager_deserialize(m, serialization, fds);
1147 :
1148 : /* Any fds left? Find some unit which wants them. This is
1149 : * useful to allow container managers to pass some file
1150 : * descriptors to us pre-initialized. This enables
1151 : * socket-based activation of entire containers. */
1152 10 : if (fdset_size(fds) > 0) {
1153 0 : q = manager_distribute_fds(m, fds);
1154 0 : if (q < 0 && r == 0)
1155 0 : r = q;
1156 : }
1157 :
1158 : /* We might have deserialized the notify fd, but if we didn't
1159 : * then let's create the bus now */
1160 10 : q = manager_setup_notify(m);
1161 10 : if (q < 0 && r == 0)
1162 0 : r = q;
1163 :
1164 : /* We might have deserialized the kdbus control fd, but if we
1165 : * didn't, then let's create the bus now. */
1166 10 : manager_setup_kdbus(m);
1167 10 : manager_connect_bus(m, !!serialization);
1168 10 : bus_track_coldplug(m, &m->subscribed, &m->deserialized_subscribed);
1169 :
1170 : /* Third, fire things up! */
1171 10 : manager_coldplug(m);
1172 :
1173 10 : if (serialization) {
1174 0 : assert(m->n_reloading > 0);
1175 0 : m->n_reloading --;
1176 :
1177 : /* Let's wait for the UnitNew/JobNew messages being
1178 : * sent, before we notify that the reload is
1179 : * finished */
1180 0 : m->send_reloading_done = true;
1181 : }
1182 :
1183 10 : return r;
1184 : }
1185 :
1186 16 : int manager_add_job(Manager *m, JobType type, Unit *unit, JobMode mode, bool override, sd_bus_error *e, Job **_ret) {
1187 : int r;
1188 : Transaction *tr;
1189 :
1190 16 : assert(m);
1191 16 : assert(type < _JOB_TYPE_MAX);
1192 16 : assert(unit);
1193 16 : assert(mode < _JOB_MODE_MAX);
1194 :
1195 16 : if (mode == JOB_ISOLATE && type != JOB_START)
1196 0 : return sd_bus_error_setf(e, SD_BUS_ERROR_INVALID_ARGS, "Isolate is only valid for start.");
1197 :
1198 16 : if (mode == JOB_ISOLATE && !unit->allow_isolate)
1199 0 : return sd_bus_error_setf(e, BUS_ERROR_NO_ISOLATION, "Operation refused, unit may not be isolated.");
1200 :
1201 16 : log_unit_debug(unit, "Trying to enqueue job %s/%s/%s", unit->id, job_type_to_string(type), job_mode_to_string(mode));
1202 :
1203 16 : type = job_type_collapse(type, unit);
1204 :
1205 16 : tr = transaction_new(mode == JOB_REPLACE_IRREVERSIBLY);
1206 16 : if (!tr)
1207 0 : return -ENOMEM;
1208 :
1209 32 : r = transaction_add_job_and_dependencies(tr, type, unit, NULL, true, override, false,
1210 16 : mode == JOB_IGNORE_DEPENDENCIES || mode == JOB_IGNORE_REQUIREMENTS,
1211 : mode == JOB_IGNORE_DEPENDENCIES, e);
1212 16 : if (r < 0)
1213 0 : goto tr_abort;
1214 :
1215 16 : if (mode == JOB_ISOLATE) {
1216 0 : r = transaction_add_isolate_jobs(tr, m);
1217 0 : if (r < 0)
1218 0 : goto tr_abort;
1219 : }
1220 :
1221 16 : r = transaction_activate(tr, m, mode, e);
1222 16 : if (r < 0)
1223 3 : goto tr_abort;
1224 :
1225 13 : log_unit_debug(unit,
1226 : "Enqueued job %s/%s as %u", unit->id,
1227 : job_type_to_string(type), (unsigned) tr->anchor_job->id);
1228 :
1229 13 : if (_ret)
1230 7 : *_ret = tr->anchor_job;
1231 :
1232 13 : transaction_free(tr);
1233 13 : return 0;
1234 :
1235 : tr_abort:
1236 3 : transaction_abort(tr);
1237 3 : transaction_free(tr);
1238 3 : return r;
1239 : }
1240 :
1241 0 : int manager_add_job_by_name(Manager *m, JobType type, const char *name, JobMode mode, bool override, sd_bus_error *e, Job **_ret) {
1242 : Unit *unit;
1243 : int r;
1244 :
1245 0 : assert(m);
1246 0 : assert(type < _JOB_TYPE_MAX);
1247 0 : assert(name);
1248 0 : assert(mode < _JOB_MODE_MAX);
1249 :
1250 0 : r = manager_load_unit(m, name, NULL, NULL, &unit);
1251 0 : if (r < 0)
1252 0 : return r;
1253 :
1254 0 : return manager_add_job(m, type, unit, mode, override, e, _ret);
1255 : }
1256 :
1257 42 : Job *manager_get_job(Manager *m, uint32_t id) {
1258 42 : assert(m);
1259 :
1260 42 : return hashmap_get(m->jobs, UINT32_TO_PTR(id));
1261 : }
1262 :
1263 1806 : Unit *manager_get_unit(Manager *m, const char *name) {
1264 1806 : assert(m);
1265 1806 : assert(name);
1266 :
1267 1806 : return hashmap_get(m->units, name);
1268 : }
1269 :
1270 162 : unsigned manager_dispatch_load_queue(Manager *m) {
1271 : Unit *u;
1272 162 : unsigned n = 0;
1273 :
1274 162 : assert(m);
1275 :
1276 : /* Make sure we are not run recursively */
1277 162 : if (m->dispatching_load_queue)
1278 130 : return 0;
1279 :
1280 32 : m->dispatching_load_queue = true;
1281 :
1282 : /* Dispatches the load queue. Takes a unit from the queue and
1283 : * tries to load its data until the queue is empty */
1284 :
1285 846 : while ((u = m->load_queue)) {
1286 782 : assert(u->in_load_queue);
1287 :
1288 782 : unit_load(u);
1289 782 : n++;
1290 : }
1291 :
1292 32 : m->dispatching_load_queue = false;
1293 32 : return n;
1294 : }
1295 :
1296 440 : int manager_load_unit_prepare(
1297 : Manager *m,
1298 : const char *name,
1299 : const char *path,
1300 : sd_bus_error *e,
1301 : Unit **_ret) {
1302 :
1303 : Unit *ret;
1304 : UnitType t;
1305 : int r;
1306 :
1307 440 : assert(m);
1308 440 : assert(name || path);
1309 :
1310 : /* This will prepare the unit for loading, but not actually
1311 : * load anything from disk. */
1312 :
1313 440 : if (path && !is_path(path))
1314 0 : return sd_bus_error_setf(e, SD_BUS_ERROR_INVALID_ARGS, "Path %s is not absolute.", path);
1315 :
1316 440 : if (!name)
1317 0 : name = basename(path);
1318 :
1319 440 : t = unit_name_to_type(name);
1320 :
1321 440 : if (t == _UNIT_TYPE_INVALID || !unit_name_is_valid(name, UNIT_NAME_PLAIN|UNIT_NAME_INSTANCE))
1322 0 : return sd_bus_error_setf(e, SD_BUS_ERROR_INVALID_ARGS, "Unit name %s is not valid.", name);
1323 :
1324 440 : ret = manager_get_unit(m, name);
1325 440 : if (ret) {
1326 288 : *_ret = ret;
1327 288 : return 1;
1328 : }
1329 :
1330 152 : ret = unit_new(m, unit_vtable[t]->object_size);
1331 152 : if (!ret)
1332 0 : return -ENOMEM;
1333 :
1334 152 : if (path) {
1335 0 : ret->fragment_path = strdup(path);
1336 0 : if (!ret->fragment_path) {
1337 0 : unit_free(ret);
1338 0 : return -ENOMEM;
1339 : }
1340 : }
1341 :
1342 152 : r = unit_add_name(ret, name);
1343 152 : if (r < 0) {
1344 0 : unit_free(ret);
1345 0 : return r;
1346 : }
1347 :
1348 152 : unit_add_to_load_queue(ret);
1349 152 : unit_add_to_dbus_queue(ret);
1350 152 : unit_add_to_gc_queue(ret);
1351 :
1352 152 : if (_ret)
1353 152 : *_ret = ret;
1354 :
1355 152 : return 0;
1356 : }
1357 :
1358 440 : int manager_load_unit(
1359 : Manager *m,
1360 : const char *name,
1361 : const char *path,
1362 : sd_bus_error *e,
1363 : Unit **_ret) {
1364 :
1365 : int r;
1366 :
1367 440 : assert(m);
1368 :
1369 : /* This will load the service information files, but not actually
1370 : * start any services or anything. */
1371 :
1372 440 : r = manager_load_unit_prepare(m, name, path, e, _ret);
1373 440 : if (r != 0)
1374 288 : return r;
1375 :
1376 152 : manager_dispatch_load_queue(m);
1377 :
1378 152 : if (_ret)
1379 152 : *_ret = unit_follow_merge(*_ret);
1380 :
1381 152 : return 0;
1382 : }
1383 :
1384 8 : void manager_dump_jobs(Manager *s, FILE *f, const char *prefix) {
1385 : Iterator i;
1386 : Job *j;
1387 :
1388 8 : assert(s);
1389 8 : assert(f);
1390 :
1391 73 : HASHMAP_FOREACH(j, s->jobs, i)
1392 57 : job_dump(j, f, prefix);
1393 8 : }
1394 :
1395 4 : void manager_dump_units(Manager *s, FILE *f, const char *prefix) {
1396 : Iterator i;
1397 : Unit *u;
1398 : const char *t;
1399 :
1400 4 : assert(s);
1401 4 : assert(f);
1402 :
1403 333 : HASHMAP_FOREACH_KEY(u, t, s->units, i)
1404 325 : if (u->id == t)
1405 325 : unit_dump(u, f, prefix);
1406 4 : }
1407 :
1408 1 : void manager_clear_jobs(Manager *m) {
1409 : Job *j;
1410 :
1411 1 : assert(m);
1412 :
1413 12 : while ((j = hashmap_first(m->jobs)))
1414 : /* No need to recurse. We're cancelling all jobs. */
1415 10 : job_finish_and_invalidate(j, JOB_CANCELED, false);
1416 1 : }
1417 :
1418 6 : static int manager_dispatch_run_queue(sd_event_source *source, void *userdata) {
1419 6 : Manager *m = userdata;
1420 : Job *j;
1421 :
1422 6 : assert(source);
1423 6 : assert(m);
1424 :
1425 67 : while ((j = m->run_queue)) {
1426 55 : assert(j->installed);
1427 55 : assert(j->in_run_queue);
1428 :
1429 55 : job_run_and_invalidate(j);
1430 : }
1431 :
1432 6 : if (m->n_running_jobs > 0)
1433 6 : manager_watch_jobs_in_progress(m);
1434 :
1435 6 : if (m->n_on_console > 0)
1436 0 : manager_watch_idle_pipe(m);
1437 :
1438 6 : return 1;
1439 : }
1440 :
1441 0 : static unsigned manager_dispatch_dbus_queue(Manager *m) {
1442 : Job *j;
1443 : Unit *u;
1444 0 : unsigned n = 0;
1445 :
1446 0 : assert(m);
1447 :
1448 0 : if (m->dispatching_dbus_queue)
1449 0 : return 0;
1450 :
1451 0 : m->dispatching_dbus_queue = true;
1452 :
1453 0 : while ((u = m->dbus_unit_queue)) {
1454 0 : assert(u->in_dbus_queue);
1455 :
1456 0 : bus_unit_send_change_signal(u);
1457 0 : n++;
1458 : }
1459 :
1460 0 : while ((j = m->dbus_job_queue)) {
1461 0 : assert(j->in_dbus_queue);
1462 :
1463 0 : bus_job_send_change_signal(j);
1464 0 : n++;
1465 : }
1466 :
1467 0 : m->dispatching_dbus_queue = false;
1468 :
1469 0 : if (m->send_reloading_done) {
1470 0 : m->send_reloading_done = false;
1471 :
1472 0 : bus_manager_send_reloading(m, false);
1473 : }
1474 :
1475 0 : if (m->queued_message)
1476 0 : bus_send_queued_message(m);
1477 :
1478 0 : return n;
1479 : }
1480 :
1481 0 : static void manager_invoke_notify_message(Manager *m, Unit *u, pid_t pid, char *buf, size_t n, FDSet *fds) {
1482 0 : _cleanup_strv_free_ char **tags = NULL;
1483 :
1484 0 : assert(m);
1485 0 : assert(u);
1486 0 : assert(buf);
1487 0 : assert(n > 0);
1488 :
1489 0 : tags = strv_split(buf, "\n\r");
1490 0 : if (!tags) {
1491 0 : log_oom();
1492 0 : return;
1493 : }
1494 :
1495 0 : if (UNIT_VTABLE(u)->notify_message)
1496 0 : UNIT_VTABLE(u)->notify_message(u, pid, tags, fds);
1497 : else
1498 0 : log_unit_debug(u, "Got notification message for unit. Ignoring.");
1499 : }
1500 :
1501 0 : static int manager_dispatch_notify_fd(sd_event_source *source, int fd, uint32_t revents, void *userdata) {
1502 0 : Manager *m = userdata;
1503 : ssize_t n;
1504 : int r;
1505 :
1506 0 : assert(m);
1507 0 : assert(m->notify_fd == fd);
1508 :
1509 0 : if (revents != EPOLLIN) {
1510 0 : log_warning("Got unexpected poll event for notify fd.");
1511 0 : return 0;
1512 : }
1513 :
1514 : for (;;) {
1515 0 : _cleanup_fdset_free_ FDSet *fds = NULL;
1516 : char buf[NOTIFY_BUFFER_MAX+1];
1517 0 : struct iovec iovec = {
1518 : .iov_base = buf,
1519 : .iov_len = sizeof(buf)-1,
1520 : };
1521 : union {
1522 : struct cmsghdr cmsghdr;
1523 : uint8_t buf[CMSG_SPACE(sizeof(struct ucred)) +
1524 : CMSG_SPACE(sizeof(int) * NOTIFY_FD_MAX)];
1525 0 : } control = {};
1526 0 : struct msghdr msghdr = {
1527 : .msg_iov = &iovec,
1528 : .msg_iovlen = 1,
1529 : .msg_control = &control,
1530 : .msg_controllen = sizeof(control),
1531 : };
1532 : struct cmsghdr *cmsg;
1533 0 : struct ucred *ucred = NULL;
1534 0 : bool found = false;
1535 : Unit *u1, *u2, *u3;
1536 0 : int *fd_array = NULL;
1537 0 : unsigned n_fds = 0;
1538 :
1539 0 : n = recvmsg(m->notify_fd, &msghdr, MSG_DONTWAIT|MSG_CMSG_CLOEXEC);
1540 0 : if (n < 0) {
1541 0 : if (errno == EAGAIN || errno == EINTR)
1542 : break;
1543 :
1544 0 : return -errno;
1545 : }
1546 :
1547 0 : CMSG_FOREACH(cmsg, &msghdr) {
1548 0 : if (cmsg->cmsg_level == SOL_SOCKET && cmsg->cmsg_type == SCM_RIGHTS) {
1549 :
1550 0 : fd_array = (int*) CMSG_DATA(cmsg);
1551 0 : n_fds = (cmsg->cmsg_len - CMSG_LEN(0)) / sizeof(int);
1552 :
1553 0 : } else if (cmsg->cmsg_level == SOL_SOCKET &&
1554 0 : cmsg->cmsg_type == SCM_CREDENTIALS &&
1555 0 : cmsg->cmsg_len == CMSG_LEN(sizeof(struct ucred))) {
1556 :
1557 0 : ucred = (struct ucred*) CMSG_DATA(cmsg);
1558 : }
1559 : }
1560 :
1561 0 : if (n_fds > 0) {
1562 0 : assert(fd_array);
1563 :
1564 0 : r = fdset_new_array(&fds, fd_array, n_fds);
1565 0 : if (r < 0) {
1566 0 : close_many(fd_array, n_fds);
1567 0 : return log_oom();
1568 : }
1569 : }
1570 :
1571 0 : if (!ucred || ucred->pid <= 0) {
1572 0 : log_warning("Received notify message without valid credentials. Ignoring.");
1573 0 : continue;
1574 : }
1575 :
1576 0 : if ((size_t) n >= sizeof(buf)) {
1577 0 : log_warning("Received notify message exceeded maximum size. Ignoring.");
1578 0 : continue;
1579 : }
1580 :
1581 0 : buf[n] = 0;
1582 :
1583 : /* Notify every unit that might be interested, but try
1584 : * to avoid notifying the same one multiple times. */
1585 0 : u1 = manager_get_unit_by_pid(m, ucred->pid);
1586 0 : if (u1) {
1587 0 : manager_invoke_notify_message(m, u1, ucred->pid, buf, n, fds);
1588 0 : found = true;
1589 : }
1590 :
1591 0 : u2 = hashmap_get(m->watch_pids1, LONG_TO_PTR(ucred->pid));
1592 0 : if (u2 && u2 != u1) {
1593 0 : manager_invoke_notify_message(m, u2, ucred->pid, buf, n, fds);
1594 0 : found = true;
1595 : }
1596 :
1597 0 : u3 = hashmap_get(m->watch_pids2, LONG_TO_PTR(ucred->pid));
1598 0 : if (u3 && u3 != u2 && u3 != u1) {
1599 0 : manager_invoke_notify_message(m, u3, ucred->pid, buf, n, fds);
1600 0 : found = true;
1601 : }
1602 :
1603 0 : if (!found)
1604 0 : log_warning("Cannot find unit for notify message of PID "PID_FMT".", ucred->pid);
1605 :
1606 0 : if (fdset_size(fds) > 0)
1607 0 : log_warning("Got auxiliary fds with notification message, closing all.");
1608 0 : }
1609 :
1610 0 : return 0;
1611 : }
1612 :
1613 0 : static void invoke_sigchld_event(Manager *m, Unit *u, siginfo_t *si) {
1614 0 : assert(m);
1615 0 : assert(u);
1616 0 : assert(si);
1617 :
1618 0 : log_unit_debug(u, "Child "PID_FMT" belongs to %s", si->si_pid, u->id);
1619 :
1620 0 : unit_unwatch_pid(u, si->si_pid);
1621 0 : UNIT_VTABLE(u)->sigchld_event(u, si->si_pid, si->si_code, si->si_status);
1622 0 : }
1623 :
1624 0 : static int manager_dispatch_sigchld(Manager *m) {
1625 0 : assert(m);
1626 :
1627 : for (;;) {
1628 0 : siginfo_t si = {};
1629 :
1630 : /* First we call waitd() for a PID and do not reap the
1631 : * zombie. That way we can still access /proc/$PID for
1632 : * it while it is a zombie. */
1633 0 : if (waitid(P_ALL, 0, &si, WEXITED|WNOHANG|WNOWAIT) < 0) {
1634 :
1635 0 : if (errno == ECHILD)
1636 0 : break;
1637 :
1638 0 : if (errno == EINTR)
1639 0 : continue;
1640 :
1641 0 : return -errno;
1642 : }
1643 :
1644 0 : if (si.si_pid <= 0)
1645 0 : break;
1646 :
1647 0 : if (si.si_code == CLD_EXITED || si.si_code == CLD_KILLED || si.si_code == CLD_DUMPED) {
1648 0 : _cleanup_free_ char *name = NULL;
1649 : Unit *u1, *u2, *u3;
1650 :
1651 0 : get_process_comm(si.si_pid, &name);
1652 :
1653 0 : log_debug("Child "PID_FMT" (%s) died (code=%s, status=%i/%s)",
1654 : si.si_pid, strna(name),
1655 : sigchld_code_to_string(si.si_code),
1656 : si.si_status,
1657 : strna(si.si_code == CLD_EXITED
1658 : ? exit_status_to_string(si.si_status, EXIT_STATUS_FULL)
1659 : : signal_to_string(si.si_status)));
1660 :
1661 : /* And now figure out the unit this belongs
1662 : * to, it might be multiple... */
1663 0 : u1 = manager_get_unit_by_pid(m, si.si_pid);
1664 0 : if (u1)
1665 0 : invoke_sigchld_event(m, u1, &si);
1666 0 : u2 = hashmap_get(m->watch_pids1, LONG_TO_PTR(si.si_pid));
1667 0 : if (u2 && u2 != u1)
1668 0 : invoke_sigchld_event(m, u2, &si);
1669 0 : u3 = hashmap_get(m->watch_pids2, LONG_TO_PTR(si.si_pid));
1670 0 : if (u3 && u3 != u2 && u3 != u1)
1671 0 : invoke_sigchld_event(m, u3, &si);
1672 : }
1673 :
1674 : /* And now, we actually reap the zombie. */
1675 0 : if (waitid(P_PID, si.si_pid, &si, WEXITED) < 0) {
1676 0 : if (errno == EINTR)
1677 0 : continue;
1678 :
1679 0 : return -errno;
1680 : }
1681 0 : }
1682 :
1683 0 : return 0;
1684 : }
1685 :
1686 0 : static int manager_start_target(Manager *m, const char *name, JobMode mode) {
1687 0 : _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
1688 : int r;
1689 :
1690 0 : log_debug("Activating special unit %s", name);
1691 :
1692 0 : r = manager_add_job_by_name(m, JOB_START, name, mode, true, &error, NULL);
1693 0 : if (r < 0)
1694 0 : log_error("Failed to enqueue %s job: %s", name, bus_error_message(&error, r));
1695 :
1696 0 : return r;
1697 : }
1698 :
1699 0 : static int manager_dispatch_signal_fd(sd_event_source *source, int fd, uint32_t revents, void *userdata) {
1700 0 : Manager *m = userdata;
1701 : ssize_t n;
1702 : struct signalfd_siginfo sfsi;
1703 0 : bool sigchld = false;
1704 :
1705 0 : assert(m);
1706 0 : assert(m->signal_fd == fd);
1707 :
1708 0 : if (revents != EPOLLIN) {
1709 0 : log_warning("Got unexpected events from signal file descriptor.");
1710 0 : return 0;
1711 : }
1712 :
1713 : for (;;) {
1714 0 : n = read(m->signal_fd, &sfsi, sizeof(sfsi));
1715 0 : if (n != sizeof(sfsi)) {
1716 :
1717 0 : if (n >= 0)
1718 0 : return -EIO;
1719 :
1720 0 : if (errno == EINTR || errno == EAGAIN)
1721 : break;
1722 :
1723 0 : return -errno;
1724 : }
1725 :
1726 0 : log_received_signal(sfsi.ssi_signo == SIGCHLD ||
1727 0 : (sfsi.ssi_signo == SIGTERM && m->running_as == MANAGER_USER)
1728 : ? LOG_DEBUG : LOG_INFO,
1729 : &sfsi);
1730 :
1731 0 : switch (sfsi.ssi_signo) {
1732 :
1733 : case SIGCHLD:
1734 0 : sigchld = true;
1735 0 : break;
1736 :
1737 : case SIGTERM:
1738 0 : if (m->running_as == MANAGER_SYSTEM) {
1739 : /* This is for compatibility with the
1740 : * original sysvinit */
1741 0 : m->exit_code = MANAGER_REEXECUTE;
1742 0 : break;
1743 : }
1744 :
1745 : /* Fall through */
1746 :
1747 : case SIGINT:
1748 0 : if (m->running_as == MANAGER_SYSTEM) {
1749 :
1750 : /* If the user presses C-A-D more than
1751 : * 7 times within 2s, we reboot
1752 : * immediately. */
1753 :
1754 0 : if (ratelimit_test(&m->ctrl_alt_del_ratelimit))
1755 0 : manager_start_target(m, SPECIAL_CTRL_ALT_DEL_TARGET, JOB_REPLACE_IRREVERSIBLY);
1756 : else {
1757 0 : log_notice("Ctrl-Alt-Del was pressed more than 7 times within 2s, rebooting immediately.");
1758 0 : status_printf(NULL, true, false, "Ctrl-Alt-Del was pressed more than 7 times within 2s, rebooting immediately.");
1759 0 : m->exit_code = MANAGER_REBOOT;
1760 : }
1761 :
1762 0 : break;
1763 : }
1764 :
1765 : /* Run the exit target if there is one, if not, just exit. */
1766 0 : if (manager_start_target(m, SPECIAL_EXIT_TARGET, JOB_REPLACE) < 0) {
1767 0 : m->exit_code = MANAGER_EXIT;
1768 0 : return 0;
1769 : }
1770 :
1771 0 : break;
1772 :
1773 : case SIGWINCH:
1774 0 : if (m->running_as == MANAGER_SYSTEM)
1775 0 : manager_start_target(m, SPECIAL_KBREQUEST_TARGET, JOB_REPLACE);
1776 :
1777 : /* This is a nop on non-init */
1778 0 : break;
1779 :
1780 : case SIGPWR:
1781 0 : if (m->running_as == MANAGER_SYSTEM)
1782 0 : manager_start_target(m, SPECIAL_SIGPWR_TARGET, JOB_REPLACE);
1783 :
1784 : /* This is a nop on non-init */
1785 0 : break;
1786 :
1787 : case SIGUSR1: {
1788 : Unit *u;
1789 :
1790 0 : u = manager_get_unit(m, SPECIAL_DBUS_SERVICE);
1791 :
1792 0 : if (!u || UNIT_IS_ACTIVE_OR_RELOADING(unit_active_state(u))) {
1793 0 : log_info("Trying to reconnect to bus...");
1794 0 : bus_init(m, true);
1795 : }
1796 :
1797 0 : if (!u || !UNIT_IS_ACTIVE_OR_ACTIVATING(unit_active_state(u))) {
1798 0 : log_info("Loading D-Bus service...");
1799 0 : manager_start_target(m, SPECIAL_DBUS_SERVICE, JOB_REPLACE);
1800 : }
1801 :
1802 0 : break;
1803 : }
1804 :
1805 : case SIGUSR2: {
1806 0 : _cleanup_free_ char *dump = NULL;
1807 0 : _cleanup_fclose_ FILE *f = NULL;
1808 : size_t size;
1809 :
1810 0 : f = open_memstream(&dump, &size);
1811 0 : if (!f) {
1812 0 : log_warning("Failed to allocate memory stream.");
1813 0 : break;
1814 : }
1815 :
1816 0 : manager_dump_units(m, f, "\t");
1817 0 : manager_dump_jobs(m, f, "\t");
1818 :
1819 0 : if (ferror(f)) {
1820 0 : log_warning("Failed to write status stream");
1821 0 : break;
1822 : }
1823 :
1824 0 : if (fflush(f)) {
1825 0 : log_warning("Failed to flush status stream");
1826 0 : break;
1827 : }
1828 :
1829 0 : log_dump(LOG_INFO, dump);
1830 0 : break;
1831 : }
1832 :
1833 : case SIGHUP:
1834 0 : m->exit_code = MANAGER_RELOAD;
1835 0 : break;
1836 :
1837 : default: {
1838 :
1839 : /* Starting SIGRTMIN+0 */
1840 : static const char * const target_table[] = {
1841 : [0] = SPECIAL_DEFAULT_TARGET,
1842 : [1] = SPECIAL_RESCUE_TARGET,
1843 : [2] = SPECIAL_EMERGENCY_TARGET,
1844 : [3] = SPECIAL_HALT_TARGET,
1845 : [4] = SPECIAL_POWEROFF_TARGET,
1846 : [5] = SPECIAL_REBOOT_TARGET,
1847 : [6] = SPECIAL_KEXEC_TARGET
1848 : };
1849 :
1850 : /* Starting SIGRTMIN+13, so that target halt and system halt are 10 apart */
1851 : static const ManagerExitCode code_table[] = {
1852 : [0] = MANAGER_HALT,
1853 : [1] = MANAGER_POWEROFF,
1854 : [2] = MANAGER_REBOOT,
1855 : [3] = MANAGER_KEXEC
1856 : };
1857 :
1858 0 : if ((int) sfsi.ssi_signo >= SIGRTMIN+0 &&
1859 0 : (int) sfsi.ssi_signo < SIGRTMIN+(int) ELEMENTSOF(target_table)) {
1860 0 : int idx = (int) sfsi.ssi_signo - SIGRTMIN;
1861 0 : manager_start_target(m, target_table[idx],
1862 0 : (idx == 1 || idx == 2) ? JOB_ISOLATE : JOB_REPLACE);
1863 0 : break;
1864 : }
1865 :
1866 0 : if ((int) sfsi.ssi_signo >= SIGRTMIN+13 &&
1867 0 : (int) sfsi.ssi_signo < SIGRTMIN+13+(int) ELEMENTSOF(code_table)) {
1868 0 : m->exit_code = code_table[sfsi.ssi_signo - SIGRTMIN - 13];
1869 0 : break;
1870 : }
1871 :
1872 0 : switch (sfsi.ssi_signo - SIGRTMIN) {
1873 :
1874 : case 20:
1875 0 : log_debug("Enabling showing of status.");
1876 0 : manager_set_show_status(m, SHOW_STATUS_YES);
1877 0 : break;
1878 :
1879 : case 21:
1880 0 : log_debug("Disabling showing of status.");
1881 0 : manager_set_show_status(m, SHOW_STATUS_NO);
1882 0 : break;
1883 :
1884 : case 22:
1885 0 : log_set_max_level(LOG_DEBUG);
1886 0 : log_notice("Setting log level to debug.");
1887 0 : break;
1888 :
1889 : case 23:
1890 0 : log_set_max_level(LOG_INFO);
1891 0 : log_notice("Setting log level to info.");
1892 0 : break;
1893 :
1894 : case 24:
1895 0 : if (m->running_as == MANAGER_USER) {
1896 0 : m->exit_code = MANAGER_EXIT;
1897 0 : return 0;
1898 : }
1899 :
1900 : /* This is a nop on init */
1901 0 : break;
1902 :
1903 : case 26:
1904 : case 29: /* compatibility: used to be mapped to LOG_TARGET_SYSLOG_OR_KMSG */
1905 0 : log_set_target(LOG_TARGET_JOURNAL_OR_KMSG);
1906 0 : log_notice("Setting log target to journal-or-kmsg.");
1907 0 : break;
1908 :
1909 : case 27:
1910 0 : log_set_target(LOG_TARGET_CONSOLE);
1911 0 : log_notice("Setting log target to console.");
1912 0 : break;
1913 :
1914 : case 28:
1915 0 : log_set_target(LOG_TARGET_KMSG);
1916 0 : log_notice("Setting log target to kmsg.");
1917 0 : break;
1918 :
1919 : default:
1920 0 : log_warning("Got unhandled signal <%s>.", signal_to_string(sfsi.ssi_signo));
1921 : }
1922 : }
1923 : }
1924 0 : }
1925 :
1926 0 : if (sigchld)
1927 0 : manager_dispatch_sigchld(m);
1928 :
1929 0 : return 0;
1930 : }
1931 :
1932 0 : static int manager_dispatch_time_change_fd(sd_event_source *source, int fd, uint32_t revents, void *userdata) {
1933 0 : Manager *m = userdata;
1934 : Iterator i;
1935 : Unit *u;
1936 :
1937 0 : assert(m);
1938 0 : assert(m->time_change_fd == fd);
1939 :
1940 0 : log_struct(LOG_INFO,
1941 : LOG_MESSAGE_ID(SD_MESSAGE_TIME_CHANGE),
1942 : LOG_MESSAGE("Time has been changed"),
1943 : NULL);
1944 :
1945 : /* Restart the watch */
1946 0 : m->time_change_event_source = sd_event_source_unref(m->time_change_event_source);
1947 0 : m->time_change_fd = safe_close(m->time_change_fd);
1948 :
1949 0 : manager_setup_time_change(m);
1950 :
1951 0 : HASHMAP_FOREACH(u, m->units, i)
1952 0 : if (UNIT_VTABLE(u)->time_change)
1953 0 : UNIT_VTABLE(u)->time_change(u);
1954 :
1955 0 : return 0;
1956 : }
1957 :
1958 0 : static int manager_dispatch_idle_pipe_fd(sd_event_source *source, int fd, uint32_t revents, void *userdata) {
1959 0 : Manager *m = userdata;
1960 :
1961 0 : assert(m);
1962 0 : assert(m->idle_pipe[2] == fd);
1963 :
1964 0 : m->no_console_output = m->n_on_console > 0;
1965 :
1966 0 : m->idle_pipe_event_source = sd_event_source_unref(m->idle_pipe_event_source);
1967 0 : manager_close_idle_pipe(m);
1968 :
1969 0 : return 0;
1970 : }
1971 :
1972 0 : static int manager_dispatch_jobs_in_progress(sd_event_source *source, usec_t usec, void *userdata) {
1973 0 : Manager *m = userdata;
1974 : int r;
1975 : uint64_t next;
1976 :
1977 0 : assert(m);
1978 0 : assert(source);
1979 :
1980 0 : manager_print_jobs_in_progress(m);
1981 :
1982 0 : next = now(CLOCK_MONOTONIC) + JOBS_IN_PROGRESS_PERIOD_USEC;
1983 0 : r = sd_event_source_set_time(source, next);
1984 0 : if (r < 0)
1985 0 : return r;
1986 :
1987 0 : return sd_event_source_set_enabled(source, SD_EVENT_ONESHOT);
1988 : }
1989 :
1990 0 : int manager_loop(Manager *m) {
1991 : int r;
1992 :
1993 0 : RATELIMIT_DEFINE(rl, 1*USEC_PER_SEC, 50000);
1994 :
1995 0 : assert(m);
1996 0 : m->exit_code = MANAGER_OK;
1997 :
1998 : /* Release the path cache */
1999 0 : set_free_free(m->unit_path_cache);
2000 0 : m->unit_path_cache = NULL;
2001 :
2002 0 : manager_check_finished(m);
2003 :
2004 : /* There might still be some zombies hanging around from
2005 : * before we were exec()'ed. Let's reap them. */
2006 0 : r = manager_dispatch_sigchld(m);
2007 0 : if (r < 0)
2008 0 : return r;
2009 :
2010 0 : while (m->exit_code == MANAGER_OK) {
2011 : usec_t wait_usec;
2012 :
2013 0 : if (m->runtime_watchdog > 0 && m->running_as == MANAGER_SYSTEM)
2014 0 : watchdog_ping();
2015 :
2016 0 : if (!ratelimit_test(&rl)) {
2017 : /* Yay, something is going seriously wrong, pause a little */
2018 0 : log_warning("Looping too fast. Throttling execution a little.");
2019 0 : sleep(1);
2020 0 : continue;
2021 : }
2022 :
2023 0 : if (manager_dispatch_load_queue(m) > 0)
2024 0 : continue;
2025 :
2026 0 : if (manager_dispatch_gc_queue(m) > 0)
2027 0 : continue;
2028 :
2029 0 : if (manager_dispatch_cleanup_queue(m) > 0)
2030 0 : continue;
2031 :
2032 0 : if (manager_dispatch_cgroup_queue(m) > 0)
2033 0 : continue;
2034 :
2035 0 : if (manager_dispatch_dbus_queue(m) > 0)
2036 0 : continue;
2037 :
2038 : /* Sleep for half the watchdog time */
2039 0 : if (m->runtime_watchdog > 0 && m->running_as == MANAGER_SYSTEM) {
2040 0 : wait_usec = m->runtime_watchdog / 2;
2041 0 : if (wait_usec <= 0)
2042 0 : wait_usec = 1;
2043 : } else
2044 0 : wait_usec = USEC_INFINITY;
2045 :
2046 0 : r = sd_event_run(m->event, wait_usec);
2047 0 : if (r < 0)
2048 0 : return log_error_errno(r, "Failed to run event loop: %m");
2049 : }
2050 :
2051 0 : return m->exit_code;
2052 : }
2053 :
2054 0 : int manager_load_unit_from_dbus_path(Manager *m, const char *s, sd_bus_error *e, Unit **_u) {
2055 0 : _cleanup_free_ char *n = NULL;
2056 : Unit *u;
2057 : int r;
2058 :
2059 0 : assert(m);
2060 0 : assert(s);
2061 0 : assert(_u);
2062 :
2063 0 : r = unit_name_from_dbus_path(s, &n);
2064 0 : if (r < 0)
2065 0 : return r;
2066 :
2067 0 : r = manager_load_unit(m, n, NULL, e, &u);
2068 0 : if (r < 0)
2069 0 : return r;
2070 :
2071 0 : *_u = u;
2072 :
2073 0 : return 0;
2074 : }
2075 :
2076 0 : int manager_get_job_from_dbus_path(Manager *m, const char *s, Job **_j) {
2077 : const char *p;
2078 : unsigned id;
2079 : Job *j;
2080 : int r;
2081 :
2082 0 : assert(m);
2083 0 : assert(s);
2084 0 : assert(_j);
2085 :
2086 0 : p = startswith(s, "/org/freedesktop/systemd1/job/");
2087 0 : if (!p)
2088 0 : return -EINVAL;
2089 :
2090 0 : r = safe_atou(p, &id);
2091 0 : if (r < 0)
2092 0 : return r;
2093 :
2094 0 : j = manager_get_job(m, id);
2095 0 : if (!j)
2096 0 : return -ENOENT;
2097 :
2098 0 : *_j = j;
2099 :
2100 0 : return 0;
2101 : }
2102 :
2103 0 : void manager_send_unit_audit(Manager *m, Unit *u, int type, bool success) {
2104 :
2105 : #ifdef HAVE_AUDIT
2106 0 : _cleanup_free_ char *p = NULL;
2107 : const char *msg;
2108 : int audit_fd, r;
2109 :
2110 0 : audit_fd = get_audit_fd();
2111 0 : if (audit_fd < 0)
2112 0 : return;
2113 :
2114 : /* Don't generate audit events if the service was already
2115 : * started and we're just deserializing */
2116 0 : if (m->n_reloading > 0)
2117 0 : return;
2118 :
2119 0 : if (m->running_as != MANAGER_SYSTEM)
2120 0 : return;
2121 :
2122 0 : if (u->type != UNIT_SERVICE)
2123 0 : return;
2124 :
2125 0 : r = unit_name_to_prefix_and_instance(u->id, &p);
2126 0 : if (r < 0) {
2127 0 : log_error_errno(r, "Failed to extract prefix and instance of unit name: %m");
2128 0 : return;
2129 : }
2130 :
2131 0 : msg = strjoina("unit=", p);
2132 0 : if (audit_log_user_comm_message(audit_fd, type, msg, "systemd", NULL, NULL, NULL, success) < 0) {
2133 0 : if (errno == EPERM)
2134 : /* We aren't allowed to send audit messages?
2135 : * Then let's not retry again. */
2136 0 : close_audit_fd();
2137 : else
2138 0 : log_warning_errno(errno, "Failed to send audit message: %m");
2139 : }
2140 : #endif
2141 :
2142 : }
2143 :
2144 673 : void manager_send_unit_plymouth(Manager *m, Unit *u) {
2145 673 : union sockaddr_union sa = PLYMOUTH_SOCKET;
2146 :
2147 673 : int n = 0;
2148 1346 : _cleanup_free_ char *message = NULL;
2149 1346 : _cleanup_close_ int fd = -1;
2150 :
2151 : /* Don't generate plymouth events if the service was already
2152 : * started and we're just deserializing */
2153 673 : if (m->n_reloading > 0)
2154 0 : return;
2155 :
2156 673 : if (m->running_as != MANAGER_SYSTEM)
2157 673 : return;
2158 :
2159 0 : if (detect_container(NULL) > 0)
2160 0 : return;
2161 :
2162 0 : if (u->type != UNIT_SERVICE &&
2163 0 : u->type != UNIT_MOUNT &&
2164 0 : u->type != UNIT_SWAP)
2165 0 : return;
2166 :
2167 : /* We set SOCK_NONBLOCK here so that we rather drop the
2168 : * message then wait for plymouth */
2169 0 : fd = socket(AF_UNIX, SOCK_STREAM|SOCK_CLOEXEC|SOCK_NONBLOCK, 0);
2170 0 : if (fd < 0) {
2171 0 : log_error_errno(errno, "socket() failed: %m");
2172 0 : return;
2173 : }
2174 :
2175 0 : if (connect(fd, &sa.sa, offsetof(struct sockaddr_un, sun_path) + 1 + strlen(sa.un.sun_path+1)) < 0) {
2176 :
2177 0 : if (!IN_SET(errno, EPIPE, EAGAIN, ENOENT, ECONNREFUSED, ECONNRESET, ECONNABORTED))
2178 0 : log_error_errno(errno, "connect() failed: %m");
2179 0 : return;
2180 : }
2181 :
2182 0 : if (asprintf(&message, "U\002%c%s%n", (int) (strlen(u->id) + 1), u->id, &n) < 0) {
2183 0 : log_oom();
2184 0 : return;
2185 : }
2186 :
2187 0 : errno = 0;
2188 0 : if (write(fd, message, n + 1) != n + 1)
2189 0 : if (!IN_SET(errno, EPIPE, EAGAIN, ENOENT, ECONNREFUSED, ECONNRESET, ECONNABORTED))
2190 0 : log_error_errno(errno, "Failed to write Plymouth message: %m");
2191 : }
2192 :
2193 0 : void manager_dispatch_bus_name_owner_changed(
2194 : Manager *m,
2195 : const char *name,
2196 : const char* old_owner,
2197 : const char *new_owner) {
2198 :
2199 : Unit *u;
2200 :
2201 0 : assert(m);
2202 0 : assert(name);
2203 :
2204 0 : u = hashmap_get(m->watch_bus, name);
2205 0 : if (!u)
2206 0 : return;
2207 :
2208 0 : UNIT_VTABLE(u)->bus_name_owner_change(u, name, old_owner, new_owner);
2209 : }
2210 :
2211 0 : int manager_open_serialization(Manager *m, FILE **_f) {
2212 : const char *path;
2213 0 : int fd = -1;
2214 : FILE *f;
2215 :
2216 0 : assert(_f);
2217 :
2218 0 : path = m->running_as == MANAGER_SYSTEM ? "/run/systemd" : "/tmp";
2219 0 : fd = open_tmpfile(path, O_RDWR|O_CLOEXEC);
2220 0 : if (fd < 0)
2221 0 : return -errno;
2222 :
2223 0 : log_debug("Serializing state to %s", path);
2224 :
2225 0 : f = fdopen(fd, "w+");
2226 0 : if (!f) {
2227 0 : safe_close(fd);
2228 0 : return -errno;
2229 : }
2230 :
2231 0 : *_f = f;
2232 :
2233 0 : return 0;
2234 : }
2235 :
2236 0 : int manager_serialize(Manager *m, FILE *f, FDSet *fds, bool switching_root) {
2237 : Iterator i;
2238 : Unit *u;
2239 : const char *t;
2240 : char **e;
2241 : int r;
2242 :
2243 0 : assert(m);
2244 0 : assert(f);
2245 0 : assert(fds);
2246 :
2247 0 : m->n_reloading ++;
2248 :
2249 0 : fprintf(f, "current-job-id=%"PRIu32"\n", m->current_job_id);
2250 0 : fprintf(f, "taint-usr=%s\n", yes_no(m->taint_usr));
2251 0 : fprintf(f, "n-installed-jobs=%u\n", m->n_installed_jobs);
2252 0 : fprintf(f, "n-failed-jobs=%u\n", m->n_failed_jobs);
2253 :
2254 0 : dual_timestamp_serialize(f, "firmware-timestamp", &m->firmware_timestamp);
2255 0 : dual_timestamp_serialize(f, "loader-timestamp", &m->loader_timestamp);
2256 0 : dual_timestamp_serialize(f, "kernel-timestamp", &m->kernel_timestamp);
2257 0 : dual_timestamp_serialize(f, "initrd-timestamp", &m->initrd_timestamp);
2258 :
2259 0 : if (!in_initrd()) {
2260 0 : dual_timestamp_serialize(f, "userspace-timestamp", &m->userspace_timestamp);
2261 0 : dual_timestamp_serialize(f, "finish-timestamp", &m->finish_timestamp);
2262 0 : dual_timestamp_serialize(f, "security-start-timestamp", &m->security_start_timestamp);
2263 0 : dual_timestamp_serialize(f, "security-finish-timestamp", &m->security_finish_timestamp);
2264 0 : dual_timestamp_serialize(f, "generators-start-timestamp", &m->generators_start_timestamp);
2265 0 : dual_timestamp_serialize(f, "generators-finish-timestamp", &m->generators_finish_timestamp);
2266 0 : dual_timestamp_serialize(f, "units-load-start-timestamp", &m->units_load_start_timestamp);
2267 0 : dual_timestamp_serialize(f, "units-load-finish-timestamp", &m->units_load_finish_timestamp);
2268 : }
2269 :
2270 0 : if (!switching_root) {
2271 0 : STRV_FOREACH(e, m->environment) {
2272 0 : _cleanup_free_ char *ce;
2273 :
2274 0 : ce = cescape(*e);
2275 0 : if (!ce)
2276 0 : return -ENOMEM;
2277 :
2278 0 : fprintf(f, "env=%s\n", *e);
2279 : }
2280 : }
2281 :
2282 0 : if (m->notify_fd >= 0) {
2283 : int copy;
2284 :
2285 0 : copy = fdset_put_dup(fds, m->notify_fd);
2286 0 : if (copy < 0)
2287 0 : return copy;
2288 :
2289 0 : fprintf(f, "notify-fd=%i\n", copy);
2290 0 : fprintf(f, "notify-socket=%s\n", m->notify_socket);
2291 : }
2292 :
2293 0 : if (m->kdbus_fd >= 0) {
2294 : int copy;
2295 :
2296 0 : copy = fdset_put_dup(fds, m->kdbus_fd);
2297 0 : if (copy < 0)
2298 0 : return copy;
2299 :
2300 0 : fprintf(f, "kdbus-fd=%i\n", copy);
2301 : }
2302 :
2303 0 : bus_track_serialize(m->subscribed, f);
2304 :
2305 0 : fputc('\n', f);
2306 :
2307 0 : HASHMAP_FOREACH_KEY(u, t, m->units, i) {
2308 0 : if (u->id != t)
2309 0 : continue;
2310 :
2311 : /* Start marker */
2312 0 : fputs(u->id, f);
2313 0 : fputc('\n', f);
2314 :
2315 0 : r = unit_serialize(u, f, fds, !switching_root);
2316 0 : if (r < 0) {
2317 0 : m->n_reloading --;
2318 0 : return r;
2319 : }
2320 : }
2321 :
2322 0 : assert(m->n_reloading > 0);
2323 0 : m->n_reloading --;
2324 :
2325 0 : if (ferror(f))
2326 0 : return -EIO;
2327 :
2328 0 : r = bus_fdset_add_all(m, fds);
2329 0 : if (r < 0)
2330 0 : return r;
2331 :
2332 0 : return 0;
2333 : }
2334 :
2335 0 : int manager_deserialize(Manager *m, FILE *f, FDSet *fds) {
2336 0 : int r = 0;
2337 :
2338 0 : assert(m);
2339 0 : assert(f);
2340 :
2341 0 : log_debug("Deserializing state...");
2342 :
2343 0 : m->n_reloading ++;
2344 :
2345 : for (;;) {
2346 : char line[LINE_MAX], *l;
2347 :
2348 0 : if (!fgets(line, sizeof(line), f)) {
2349 0 : if (feof(f))
2350 0 : r = 0;
2351 : else
2352 0 : r = -errno;
2353 :
2354 0 : goto finish;
2355 : }
2356 :
2357 0 : char_array_0(line);
2358 0 : l = strstrip(line);
2359 :
2360 0 : if (l[0] == 0)
2361 0 : break;
2362 :
2363 0 : if (startswith(l, "current-job-id=")) {
2364 : uint32_t id;
2365 :
2366 0 : if (safe_atou32(l+15, &id) < 0)
2367 0 : log_debug("Failed to parse current job id value %s", l+15);
2368 : else
2369 0 : m->current_job_id = MAX(m->current_job_id, id);
2370 :
2371 0 : } else if (startswith(l, "n-installed-jobs=")) {
2372 : uint32_t n;
2373 :
2374 0 : if (safe_atou32(l+17, &n) < 0)
2375 0 : log_debug("Failed to parse installed jobs counter %s", l+17);
2376 : else
2377 0 : m->n_installed_jobs += n;
2378 :
2379 0 : } else if (startswith(l, "n-failed-jobs=")) {
2380 : uint32_t n;
2381 :
2382 0 : if (safe_atou32(l+14, &n) < 0)
2383 0 : log_debug("Failed to parse failed jobs counter %s", l+14);
2384 : else
2385 0 : m->n_failed_jobs += n;
2386 :
2387 0 : } else if (startswith(l, "taint-usr=")) {
2388 : int b;
2389 :
2390 0 : b = parse_boolean(l+10);
2391 0 : if (b < 0)
2392 0 : log_debug("Failed to parse taint /usr flag %s", l+10);
2393 : else
2394 0 : m->taint_usr = m->taint_usr || b;
2395 :
2396 0 : } else if (startswith(l, "firmware-timestamp="))
2397 0 : dual_timestamp_deserialize(l+19, &m->firmware_timestamp);
2398 0 : else if (startswith(l, "loader-timestamp="))
2399 0 : dual_timestamp_deserialize(l+17, &m->loader_timestamp);
2400 0 : else if (startswith(l, "kernel-timestamp="))
2401 0 : dual_timestamp_deserialize(l+17, &m->kernel_timestamp);
2402 0 : else if (startswith(l, "initrd-timestamp="))
2403 0 : dual_timestamp_deserialize(l+17, &m->initrd_timestamp);
2404 0 : else if (startswith(l, "userspace-timestamp="))
2405 0 : dual_timestamp_deserialize(l+20, &m->userspace_timestamp);
2406 0 : else if (startswith(l, "finish-timestamp="))
2407 0 : dual_timestamp_deserialize(l+17, &m->finish_timestamp);
2408 0 : else if (startswith(l, "security-start-timestamp="))
2409 0 : dual_timestamp_deserialize(l+25, &m->security_start_timestamp);
2410 0 : else if (startswith(l, "security-finish-timestamp="))
2411 0 : dual_timestamp_deserialize(l+26, &m->security_finish_timestamp);
2412 0 : else if (startswith(l, "generators-start-timestamp="))
2413 0 : dual_timestamp_deserialize(l+27, &m->generators_start_timestamp);
2414 0 : else if (startswith(l, "generators-finish-timestamp="))
2415 0 : dual_timestamp_deserialize(l+28, &m->generators_finish_timestamp);
2416 0 : else if (startswith(l, "units-load-start-timestamp="))
2417 0 : dual_timestamp_deserialize(l+27, &m->units_load_start_timestamp);
2418 0 : else if (startswith(l, "units-load-finish-timestamp="))
2419 0 : dual_timestamp_deserialize(l+28, &m->units_load_finish_timestamp);
2420 0 : else if (startswith(l, "env=")) {
2421 0 : _cleanup_free_ char *uce = NULL;
2422 : char **e;
2423 :
2424 0 : r = cunescape(l + 4, UNESCAPE_RELAX, &uce);
2425 0 : if (r < 0)
2426 0 : goto finish;
2427 :
2428 0 : e = strv_env_set(m->environment, uce);
2429 0 : if (!e) {
2430 0 : r = -ENOMEM;
2431 0 : goto finish;
2432 : }
2433 :
2434 0 : strv_free(m->environment);
2435 0 : m->environment = e;
2436 :
2437 0 : } else if (startswith(l, "notify-fd=")) {
2438 : int fd;
2439 :
2440 0 : if (safe_atoi(l + 10, &fd) < 0 || fd < 0 || !fdset_contains(fds, fd))
2441 0 : log_debug("Failed to parse notify fd: %s", l + 10);
2442 : else {
2443 0 : m->notify_event_source = sd_event_source_unref(m->notify_event_source);
2444 0 : safe_close(m->notify_fd);
2445 0 : m->notify_fd = fdset_remove(fds, fd);
2446 : }
2447 :
2448 0 : } else if (startswith(l, "notify-socket=")) {
2449 : char *n;
2450 :
2451 0 : n = strdup(l+14);
2452 0 : if (!n) {
2453 0 : r = -ENOMEM;
2454 0 : goto finish;
2455 : }
2456 :
2457 0 : free(m->notify_socket);
2458 0 : m->notify_socket = n;
2459 :
2460 0 : } else if (startswith(l, "kdbus-fd=")) {
2461 : int fd;
2462 :
2463 0 : if (safe_atoi(l + 9, &fd) < 0 || fd < 0 || !fdset_contains(fds, fd))
2464 0 : log_debug("Failed to parse kdbus fd: %s", l + 9);
2465 : else {
2466 0 : safe_close(m->kdbus_fd);
2467 0 : m->kdbus_fd = fdset_remove(fds, fd);
2468 : }
2469 :
2470 : } else {
2471 : int k;
2472 :
2473 0 : k = bus_track_deserialize_item(&m->deserialized_subscribed, l);
2474 0 : if (k < 0)
2475 0 : log_debug_errno(k, "Failed to deserialize bus tracker object: %m");
2476 0 : else if (k == 0)
2477 0 : log_debug("Unknown serialization item '%s'", l);
2478 : }
2479 0 : }
2480 :
2481 : for (;;) {
2482 : Unit *u;
2483 : char name[UNIT_NAME_MAX+2];
2484 :
2485 : /* Start marker */
2486 0 : if (!fgets(name, sizeof(name), f)) {
2487 0 : if (feof(f))
2488 0 : r = 0;
2489 : else
2490 0 : r = -errno;
2491 :
2492 0 : goto finish;
2493 : }
2494 :
2495 0 : char_array_0(name);
2496 :
2497 0 : r = manager_load_unit(m, strstrip(name), NULL, NULL, &u);
2498 0 : if (r < 0)
2499 0 : goto finish;
2500 :
2501 0 : r = unit_deserialize(u, f, fds);
2502 0 : if (r < 0)
2503 0 : goto finish;
2504 0 : }
2505 :
2506 : finish:
2507 0 : if (ferror(f))
2508 0 : r = -EIO;
2509 :
2510 0 : assert(m->n_reloading > 0);
2511 0 : m->n_reloading --;
2512 :
2513 0 : return r;
2514 : }
2515 :
2516 0 : int manager_reload(Manager *m) {
2517 : int r, q;
2518 0 : _cleanup_fclose_ FILE *f = NULL;
2519 0 : _cleanup_fdset_free_ FDSet *fds = NULL;
2520 :
2521 0 : assert(m);
2522 :
2523 0 : r = manager_open_serialization(m, &f);
2524 0 : if (r < 0)
2525 0 : return r;
2526 :
2527 0 : m->n_reloading ++;
2528 0 : bus_manager_send_reloading(m, true);
2529 :
2530 0 : fds = fdset_new();
2531 0 : if (!fds) {
2532 0 : m->n_reloading --;
2533 0 : return -ENOMEM;
2534 : }
2535 :
2536 0 : r = manager_serialize(m, f, fds, false);
2537 0 : if (r < 0) {
2538 0 : m->n_reloading --;
2539 0 : return r;
2540 : }
2541 :
2542 0 : if (fseeko(f, 0, SEEK_SET) < 0) {
2543 0 : m->n_reloading --;
2544 0 : return -errno;
2545 : }
2546 :
2547 : /* From here on there is no way back. */
2548 0 : manager_clear_jobs_and_units(m);
2549 0 : manager_undo_generators(m);
2550 0 : lookup_paths_free(&m->lookup_paths);
2551 :
2552 : /* Find new unit paths */
2553 0 : q = manager_run_generators(m);
2554 0 : if (q < 0 && r >= 0)
2555 0 : r = q;
2556 :
2557 0 : q = lookup_paths_init(
2558 : &m->lookup_paths, m->running_as, true,
2559 : NULL,
2560 0 : m->generator_unit_path,
2561 0 : m->generator_unit_path_early,
2562 0 : m->generator_unit_path_late);
2563 0 : if (q < 0 && r >= 0)
2564 0 : r = q;
2565 :
2566 0 : manager_build_unit_path_cache(m);
2567 :
2568 : /* First, enumerate what we can from all config files */
2569 0 : q = manager_enumerate(m);
2570 0 : if (q < 0 && r >= 0)
2571 0 : r = q;
2572 :
2573 : /* Second, deserialize our stored data */
2574 0 : q = manager_deserialize(m, f, fds);
2575 0 : if (q < 0 && r >= 0)
2576 0 : r = q;
2577 :
2578 0 : fclose(f);
2579 0 : f = NULL;
2580 :
2581 : /* Re-register notify_fd as event source */
2582 0 : q = manager_setup_notify(m);
2583 0 : if (q < 0 && r >= 0)
2584 0 : r = q;
2585 :
2586 : /* Third, fire things up! */
2587 0 : manager_coldplug(m);
2588 :
2589 0 : assert(m->n_reloading > 0);
2590 0 : m->n_reloading--;
2591 :
2592 0 : m->send_reloading_done = true;
2593 :
2594 0 : return r;
2595 : }
2596 :
2597 0 : bool manager_is_reloading_or_reexecuting(Manager *m) {
2598 0 : assert(m);
2599 :
2600 0 : return m->n_reloading != 0;
2601 : }
2602 :
2603 0 : void manager_reset_failed(Manager *m) {
2604 : Unit *u;
2605 : Iterator i;
2606 :
2607 0 : assert(m);
2608 :
2609 0 : HASHMAP_FOREACH(u, m->units, i)
2610 0 : unit_reset_failed(u);
2611 0 : }
2612 :
2613 0 : bool manager_unit_inactive_or_pending(Manager *m, const char *name) {
2614 : Unit *u;
2615 :
2616 0 : assert(m);
2617 0 : assert(name);
2618 :
2619 : /* Returns true if the unit is inactive or going down */
2620 0 : u = manager_get_unit(m, name);
2621 0 : if (!u)
2622 0 : return true;
2623 :
2624 0 : return unit_inactive_or_pending(u);
2625 : }
2626 :
2627 0 : static void manager_notify_finished(Manager *m) {
2628 : char userspace[FORMAT_TIMESPAN_MAX], initrd[FORMAT_TIMESPAN_MAX], kernel[FORMAT_TIMESPAN_MAX], sum[FORMAT_TIMESPAN_MAX];
2629 : usec_t firmware_usec, loader_usec, kernel_usec, initrd_usec, userspace_usec, total_usec;
2630 :
2631 0 : if (m->test_run)
2632 0 : return;
2633 :
2634 0 : if (m->running_as == MANAGER_SYSTEM && detect_container(NULL) <= 0) {
2635 :
2636 : /* Note that m->kernel_usec.monotonic is always at 0,
2637 : * and m->firmware_usec.monotonic and
2638 : * m->loader_usec.monotonic should be considered
2639 : * negative values. */
2640 :
2641 0 : firmware_usec = m->firmware_timestamp.monotonic - m->loader_timestamp.monotonic;
2642 0 : loader_usec = m->loader_timestamp.monotonic - m->kernel_timestamp.monotonic;
2643 0 : userspace_usec = m->finish_timestamp.monotonic - m->userspace_timestamp.monotonic;
2644 0 : total_usec = m->firmware_timestamp.monotonic + m->finish_timestamp.monotonic;
2645 :
2646 0 : if (dual_timestamp_is_set(&m->initrd_timestamp)) {
2647 :
2648 0 : kernel_usec = m->initrd_timestamp.monotonic - m->kernel_timestamp.monotonic;
2649 0 : initrd_usec = m->userspace_timestamp.monotonic - m->initrd_timestamp.monotonic;
2650 :
2651 0 : log_struct(LOG_INFO,
2652 : LOG_MESSAGE_ID(SD_MESSAGE_STARTUP_FINISHED),
2653 : "KERNEL_USEC="USEC_FMT, kernel_usec,
2654 : "INITRD_USEC="USEC_FMT, initrd_usec,
2655 : "USERSPACE_USEC="USEC_FMT, userspace_usec,
2656 : LOG_MESSAGE("Startup finished in %s (kernel) + %s (initrd) + %s (userspace) = %s.",
2657 : format_timespan(kernel, sizeof(kernel), kernel_usec, USEC_PER_MSEC),
2658 : format_timespan(initrd, sizeof(initrd), initrd_usec, USEC_PER_MSEC),
2659 : format_timespan(userspace, sizeof(userspace), userspace_usec, USEC_PER_MSEC),
2660 : format_timespan(sum, sizeof(sum), total_usec, USEC_PER_MSEC)),
2661 : NULL);
2662 : } else {
2663 0 : kernel_usec = m->userspace_timestamp.monotonic - m->kernel_timestamp.monotonic;
2664 0 : initrd_usec = 0;
2665 :
2666 0 : log_struct(LOG_INFO,
2667 : LOG_MESSAGE_ID(SD_MESSAGE_STARTUP_FINISHED),
2668 : "KERNEL_USEC="USEC_FMT, kernel_usec,
2669 : "USERSPACE_USEC="USEC_FMT, userspace_usec,
2670 : LOG_MESSAGE("Startup finished in %s (kernel) + %s (userspace) = %s.",
2671 : format_timespan(kernel, sizeof(kernel), kernel_usec, USEC_PER_MSEC),
2672 : format_timespan(userspace, sizeof(userspace), userspace_usec, USEC_PER_MSEC),
2673 : format_timespan(sum, sizeof(sum), total_usec, USEC_PER_MSEC)),
2674 : NULL);
2675 : }
2676 : } else {
2677 0 : firmware_usec = loader_usec = initrd_usec = kernel_usec = 0;
2678 0 : total_usec = userspace_usec = m->finish_timestamp.monotonic - m->userspace_timestamp.monotonic;
2679 :
2680 0 : log_struct(LOG_INFO,
2681 : LOG_MESSAGE_ID(SD_MESSAGE_STARTUP_FINISHED),
2682 : "USERSPACE_USEC="USEC_FMT, userspace_usec,
2683 : LOG_MESSAGE("Startup finished in %s.",
2684 : format_timespan(sum, sizeof(sum), total_usec, USEC_PER_MSEC)),
2685 : NULL);
2686 : }
2687 :
2688 0 : bus_manager_send_finished(m, firmware_usec, loader_usec, kernel_usec, initrd_usec, userspace_usec, total_usec);
2689 :
2690 0 : sd_notifyf(false,
2691 : "READY=1\n"
2692 : "STATUS=Startup finished in %s.",
2693 : format_timespan(sum, sizeof(sum), total_usec, USEC_PER_MSEC));
2694 : }
2695 :
2696 48 : void manager_check_finished(Manager *m) {
2697 48 : Unit *u = NULL;
2698 : Iterator i;
2699 :
2700 48 : assert(m);
2701 :
2702 48 : if (m->n_reloading > 0)
2703 48 : return;
2704 :
2705 : /* Verify that we are actually running currently. Initially
2706 : * the exit code is set to invalid, and during operation it is
2707 : * then set to MANAGER_OK */
2708 48 : if (m->exit_code != MANAGER_OK)
2709 48 : return;
2710 :
2711 0 : if (hashmap_size(m->jobs) > 0) {
2712 :
2713 0 : if (m->jobs_in_progress_event_source)
2714 : /* Ignore any failure, this is only for feedback */
2715 0 : (void) sd_event_source_set_time(m->jobs_in_progress_event_source,
2716 0 : now(CLOCK_MONOTONIC) + JOBS_IN_PROGRESS_WAIT_USEC);
2717 :
2718 0 : return;
2719 : }
2720 :
2721 0 : manager_flip_auto_status(m, false);
2722 :
2723 : /* Notify Type=idle units that we are done now */
2724 0 : m->idle_pipe_event_source = sd_event_source_unref(m->idle_pipe_event_source);
2725 0 : manager_close_idle_pipe(m);
2726 :
2727 : /* Turn off confirm spawn now */
2728 0 : m->confirm_spawn = false;
2729 :
2730 : /* No need to update ask password status when we're going non-interactive */
2731 0 : manager_close_ask_password(m);
2732 :
2733 : /* This is no longer the first boot */
2734 0 : manager_set_first_boot(m, false);
2735 :
2736 0 : if (dual_timestamp_is_set(&m->finish_timestamp))
2737 0 : return;
2738 :
2739 0 : dual_timestamp_get(&m->finish_timestamp);
2740 :
2741 0 : manager_notify_finished(m);
2742 :
2743 0 : SET_FOREACH(u, m->startup_units, i)
2744 0 : if (u->cgroup_path)
2745 0 : cgroup_context_apply(unit_get_cgroup_context(u), unit_get_cgroup_mask(u), u->cgroup_path, manager_state(m));
2746 : }
2747 :
2748 0 : static int create_generator_dir(Manager *m, char **generator, const char *name) {
2749 : char *p;
2750 : int r;
2751 :
2752 0 : assert(m);
2753 0 : assert(generator);
2754 0 : assert(name);
2755 :
2756 0 : if (*generator)
2757 0 : return 0;
2758 :
2759 0 : if (m->running_as == MANAGER_SYSTEM && getpid() == 1) {
2760 : /* systemd --system, not running --test */
2761 :
2762 0 : p = strappend("/run/systemd/", name);
2763 0 : if (!p)
2764 0 : return log_oom();
2765 :
2766 0 : r = mkdir_p_label(p, 0755);
2767 0 : if (r < 0) {
2768 0 : log_error_errno(r, "Failed to create generator directory %s: %m", p);
2769 0 : free(p);
2770 0 : return r;
2771 : }
2772 0 : } else if (m->running_as == MANAGER_USER) {
2773 0 : const char *s = NULL;
2774 :
2775 0 : s = getenv("XDG_RUNTIME_DIR");
2776 0 : if (!s)
2777 0 : return -EINVAL;
2778 0 : p = strjoin(s, "/systemd/", name, NULL);
2779 0 : if (!p)
2780 0 : return log_oom();
2781 :
2782 0 : r = mkdir_p_label(p, 0755);
2783 0 : if (r < 0) {
2784 0 : log_error_errno(r, "Failed to create generator directory %s: %m", p);
2785 0 : free(p);
2786 0 : return r;
2787 : }
2788 : } else {
2789 : /* systemd --system --test */
2790 :
2791 0 : p = strjoin("/tmp/systemd-", name, ".XXXXXX", NULL);
2792 0 : if (!p)
2793 0 : return log_oom();
2794 :
2795 0 : if (!mkdtemp(p)) {
2796 0 : log_error_errno(errno, "Failed to create generator directory %s: %m",
2797 : p);
2798 0 : free(p);
2799 0 : return -errno;
2800 : }
2801 : }
2802 :
2803 0 : *generator = p;
2804 0 : return 0;
2805 : }
2806 :
2807 0 : static void trim_generator_dir(Manager *m, char **generator) {
2808 0 : assert(m);
2809 0 : assert(generator);
2810 :
2811 0 : if (!*generator)
2812 0 : return;
2813 :
2814 0 : if (rmdir(*generator) >= 0) {
2815 0 : free(*generator);
2816 0 : *generator = NULL;
2817 : }
2818 :
2819 0 : return;
2820 : }
2821 :
2822 10 : static int manager_run_generators(Manager *m) {
2823 20 : _cleanup_strv_free_ char **paths = NULL;
2824 : const char *argv[5];
2825 : char **path;
2826 : int r;
2827 :
2828 10 : assert(m);
2829 :
2830 10 : if (m->test_run)
2831 10 : return 0;
2832 :
2833 0 : paths = generator_paths(m->running_as);
2834 0 : if (!paths)
2835 0 : return log_oom();
2836 :
2837 : /* Optimize by skipping the whole process by not creating output directories
2838 : * if no generators are found. */
2839 0 : STRV_FOREACH(path, paths) {
2840 0 : r = access(*path, F_OK);
2841 0 : if (r == 0)
2842 0 : goto found;
2843 0 : if (errno != ENOENT)
2844 0 : log_warning_errno(errno, "Failed to open generator directory %s: %m", *path);
2845 : }
2846 0 : return 0;
2847 :
2848 : found:
2849 0 : r = create_generator_dir(m, &m->generator_unit_path, "generator");
2850 0 : if (r < 0)
2851 0 : goto finish;
2852 :
2853 0 : r = create_generator_dir(m, &m->generator_unit_path_early, "generator.early");
2854 0 : if (r < 0)
2855 0 : goto finish;
2856 :
2857 0 : r = create_generator_dir(m, &m->generator_unit_path_late, "generator.late");
2858 0 : if (r < 0)
2859 0 : goto finish;
2860 :
2861 0 : argv[0] = NULL; /* Leave this empty, execute_directory() will fill something in */
2862 0 : argv[1] = m->generator_unit_path;
2863 0 : argv[2] = m->generator_unit_path_early;
2864 0 : argv[3] = m->generator_unit_path_late;
2865 0 : argv[4] = NULL;
2866 :
2867 0 : RUN_WITH_UMASK(0022)
2868 0 : execute_directories((const char* const*) paths, DEFAULT_TIMEOUT_USEC, (char**) argv);
2869 :
2870 : finish:
2871 0 : trim_generator_dir(m, &m->generator_unit_path);
2872 0 : trim_generator_dir(m, &m->generator_unit_path_early);
2873 0 : trim_generator_dir(m, &m->generator_unit_path_late);
2874 0 : return r;
2875 : }
2876 :
2877 33 : static void remove_generator_dir(Manager *m, char **generator) {
2878 33 : assert(m);
2879 33 : assert(generator);
2880 :
2881 33 : if (!*generator)
2882 33 : return;
2883 :
2884 0 : strv_remove(m->lookup_paths.unit_path, *generator);
2885 0 : (void) rm_rf(*generator, REMOVE_ROOT);
2886 :
2887 0 : free(*generator);
2888 0 : *generator = NULL;
2889 : }
2890 :
2891 11 : static void manager_undo_generators(Manager *m) {
2892 11 : assert(m);
2893 :
2894 11 : remove_generator_dir(m, &m->generator_unit_path);
2895 11 : remove_generator_dir(m, &m->generator_unit_path_early);
2896 11 : remove_generator_dir(m, &m->generator_unit_path_late);
2897 11 : }
2898 :
2899 0 : int manager_environment_add(Manager *m, char **minus, char **plus) {
2900 0 : char **a = NULL, **b = NULL, **l;
2901 0 : assert(m);
2902 :
2903 0 : l = m->environment;
2904 :
2905 0 : if (!strv_isempty(minus)) {
2906 0 : a = strv_env_delete(l, 1, minus);
2907 0 : if (!a)
2908 0 : return -ENOMEM;
2909 :
2910 0 : l = a;
2911 : }
2912 :
2913 0 : if (!strv_isempty(plus)) {
2914 0 : b = strv_env_merge(2, l, plus);
2915 0 : if (!b) {
2916 0 : strv_free(a);
2917 0 : return -ENOMEM;
2918 : }
2919 :
2920 0 : l = b;
2921 : }
2922 :
2923 0 : if (m->environment != l)
2924 0 : strv_free(m->environment);
2925 0 : if (a != l)
2926 0 : strv_free(a);
2927 0 : if (b != l)
2928 0 : strv_free(b);
2929 :
2930 0 : m->environment = l;
2931 0 : manager_clean_environment(m);
2932 0 : strv_sort(m->environment);
2933 :
2934 0 : return 0;
2935 : }
2936 :
2937 0 : int manager_set_default_rlimits(Manager *m, struct rlimit **default_rlimit) {
2938 : int i;
2939 :
2940 0 : assert(m);
2941 :
2942 0 : for (i = 0; i < _RLIMIT_MAX; i++) {
2943 0 : if (!default_rlimit[i])
2944 0 : continue;
2945 :
2946 0 : m->rlimit[i] = newdup(struct rlimit, default_rlimit[i], 1);
2947 0 : if (!m->rlimit[i])
2948 0 : return -ENOMEM;
2949 : }
2950 :
2951 0 : return 0;
2952 : }
2953 :
2954 692 : void manager_recheck_journal(Manager *m) {
2955 : Unit *u;
2956 :
2957 692 : assert(m);
2958 :
2959 692 : if (m->running_as != MANAGER_SYSTEM)
2960 692 : return;
2961 :
2962 0 : u = manager_get_unit(m, SPECIAL_JOURNALD_SOCKET);
2963 0 : if (u && SOCKET(u)->state != SOCKET_RUNNING) {
2964 0 : log_close_journal();
2965 0 : return;
2966 : }
2967 :
2968 0 : u = manager_get_unit(m, SPECIAL_JOURNALD_SERVICE);
2969 0 : if (u && SERVICE(u)->state != SERVICE_RUNNING) {
2970 0 : log_close_journal();
2971 0 : return;
2972 : }
2973 :
2974 : /* Hmm, OK, so the socket is fully up and the service is up
2975 : * too, then let's make use of the thing. */
2976 0 : log_open();
2977 : }
2978 :
2979 0 : void manager_set_show_status(Manager *m, ShowStatus mode) {
2980 0 : assert(m);
2981 0 : assert(IN_SET(mode, SHOW_STATUS_AUTO, SHOW_STATUS_NO, SHOW_STATUS_YES, SHOW_STATUS_TEMPORARY));
2982 :
2983 0 : if (m->running_as != MANAGER_SYSTEM)
2984 0 : return;
2985 :
2986 0 : m->show_status = mode;
2987 :
2988 0 : if (mode > 0)
2989 0 : touch("/run/systemd/show-status");
2990 : else
2991 0 : unlink("/run/systemd/show-status");
2992 : }
2993 :
2994 44 : static bool manager_get_show_status(Manager *m, StatusType type) {
2995 44 : assert(m);
2996 :
2997 44 : if (m->running_as != MANAGER_SYSTEM)
2998 44 : return false;
2999 :
3000 0 : if (m->no_console_output)
3001 0 : return false;
3002 :
3003 0 : if (!IN_SET(manager_state(m), MANAGER_INITIALIZING, MANAGER_STARTING, MANAGER_STOPPING))
3004 0 : return false;
3005 :
3006 : /* If we cannot find out the status properly, just proceed. */
3007 0 : if (type != STATUS_TYPE_EMERGENCY && manager_check_ask_password(m) > 0)
3008 0 : return false;
3009 :
3010 0 : if (m->show_status > 0)
3011 0 : return true;
3012 :
3013 0 : return false;
3014 : }
3015 :
3016 0 : void manager_set_first_boot(Manager *m, bool b) {
3017 0 : assert(m);
3018 :
3019 0 : if (m->running_as != MANAGER_SYSTEM)
3020 0 : return;
3021 :
3022 0 : m->first_boot = b;
3023 :
3024 0 : if (m->first_boot)
3025 0 : touch("/run/systemd/first-boot");
3026 : else
3027 0 : unlink("/run/systemd/first-boot");
3028 : }
3029 :
3030 44 : void manager_status_printf(Manager *m, StatusType type, const char *status, const char *format, ...) {
3031 : va_list ap;
3032 :
3033 : /* If m is NULL, assume we're after shutdown and let the messages through. */
3034 :
3035 44 : if (m && !manager_get_show_status(m, type))
3036 88 : return;
3037 :
3038 : /* XXX We should totally drop the check for ephemeral here
3039 : * and thus effectively make 'Type=idle' pointless. */
3040 0 : if (type == STATUS_TYPE_EPHEMERAL && m && m->n_on_console > 0)
3041 0 : return;
3042 :
3043 0 : va_start(ap, format);
3044 0 : status_vprintf(status, true, type == STATUS_TYPE_EPHEMERAL, format, ap);
3045 0 : va_end(ap);
3046 : }
3047 :
3048 580 : int manager_get_unit_by_path(Manager *m, const char *path, const char *suffix, Unit **_found) {
3049 1160 : _cleanup_free_ char *p = NULL;
3050 : Unit *found;
3051 : int r;
3052 :
3053 580 : assert(m);
3054 580 : assert(path);
3055 580 : assert(suffix);
3056 580 : assert(_found);
3057 :
3058 580 : r = unit_name_from_path(path, suffix, &p);
3059 580 : if (r < 0)
3060 0 : return r;
3061 :
3062 580 : found = manager_get_unit(m, p);
3063 580 : if (!found) {
3064 343 : *_found = NULL;
3065 343 : return 0;
3066 : }
3067 :
3068 237 : *_found = found;
3069 237 : return 1;
3070 : }
3071 :
3072 80 : Set *manager_get_units_requiring_mounts_for(Manager *m, const char *path) {
3073 80 : char p[strlen(path)+1];
3074 :
3075 80 : assert(m);
3076 80 : assert(path);
3077 :
3078 80 : strcpy(p, path);
3079 80 : path_kill_slashes(p);
3080 :
3081 80 : return hashmap_get(m->units_requiring_mounts_for, streq(p, "/") ? "" : p);
3082 : }
3083 :
3084 6 : const char *manager_get_runtime_prefix(Manager *m) {
3085 6 : assert(m);
3086 :
3087 12 : return m->running_as == MANAGER_SYSTEM ?
3088 6 : "/run" :
3089 : getenv("XDG_RUNTIME_DIR");
3090 : }
3091 :
3092 1476 : void manager_update_failed_units(Manager *m, Unit *u, bool failed) {
3093 : unsigned size;
3094 :
3095 1476 : assert(m);
3096 1476 : assert(u->manager == m);
3097 :
3098 1476 : size = set_size(m->failed_units);
3099 :
3100 1476 : if (failed) {
3101 0 : if (set_put(m->failed_units, u) < 0)
3102 0 : log_oom();
3103 : } else
3104 1476 : set_remove(m->failed_units, u);
3105 :
3106 1476 : if (set_size(m->failed_units) != size)
3107 0 : bus_manager_send_change_signal(m);
3108 1476 : }
3109 :
3110 12 : ManagerState manager_state(Manager *m) {
3111 : Unit *u;
3112 :
3113 12 : assert(m);
3114 :
3115 : /* Did we ever finish booting? If not then we are still starting up */
3116 12 : if (!dual_timestamp_is_set(&m->finish_timestamp)) {
3117 :
3118 12 : u = manager_get_unit(m, SPECIAL_BASIC_TARGET);
3119 12 : if (!u || !UNIT_IS_ACTIVE_OR_RELOADING(unit_active_state(u)))
3120 4 : return MANAGER_INITIALIZING;
3121 :
3122 8 : return MANAGER_STARTING;
3123 : }
3124 :
3125 : /* Is the special shutdown target queued? If so, we are in shutdown state */
3126 0 : u = manager_get_unit(m, SPECIAL_SHUTDOWN_TARGET);
3127 0 : if (u && u->job && IN_SET(u->job->type, JOB_START, JOB_RESTART, JOB_TRY_RESTART, JOB_RELOAD_OR_START))
3128 0 : return MANAGER_STOPPING;
3129 :
3130 : /* Are the rescue or emergency targets active or queued? If so we are in maintenance state */
3131 0 : u = manager_get_unit(m, SPECIAL_RESCUE_TARGET);
3132 0 : if (u && (UNIT_IS_ACTIVE_OR_ACTIVATING(unit_active_state(u)) ||
3133 0 : (u->job && IN_SET(u->job->type, JOB_START, JOB_RESTART, JOB_TRY_RESTART, JOB_RELOAD_OR_START))))
3134 0 : return MANAGER_MAINTENANCE;
3135 :
3136 0 : u = manager_get_unit(m, SPECIAL_EMERGENCY_TARGET);
3137 0 : if (u && (UNIT_IS_ACTIVE_OR_ACTIVATING(unit_active_state(u)) ||
3138 0 : (u->job && IN_SET(u->job->type, JOB_START, JOB_RESTART, JOB_TRY_RESTART, JOB_RELOAD_OR_START))))
3139 0 : return MANAGER_MAINTENANCE;
3140 :
3141 : /* Are there any failed units? If so, we are in degraded mode */
3142 0 : if (set_size(m->failed_units) > 0)
3143 0 : return MANAGER_DEGRADED;
3144 :
3145 0 : return MANAGER_RUNNING;
3146 : }
3147 :
3148 : static const char *const manager_state_table[_MANAGER_STATE_MAX] = {
3149 : [MANAGER_INITIALIZING] = "initializing",
3150 : [MANAGER_STARTING] = "starting",
3151 : [MANAGER_RUNNING] = "running",
3152 : [MANAGER_DEGRADED] = "degraded",
3153 : [MANAGER_MAINTENANCE] = "maintenance",
3154 : [MANAGER_STOPPING] = "stopping",
3155 : };
3156 :
3157 16 : DEFINE_STRING_TABLE_LOOKUP(manager_state, ManagerState);
|