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