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