]> git.ipfire.org Git - thirdparty/systemd.git/blame - src/manager.c
journalctl: always show monotonic timestamp even if it's from an old boot
[thirdparty/systemd.git] / src / manager.c
CommitLineData
d6c9574f 1/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
60918275 2
a7334b09
LP
3/***
4 This file is part of systemd.
5
6 Copyright 2010 Lennart Poettering
7
8 systemd is free software; you can redistribute it and/or modify it
9 under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 2 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 General Public License for more details.
17
18 You should have received a copy of the GNU General Public License
19 along with systemd; If not, see <http://www.gnu.org/licenses/>.
20***/
21
60918275
LP
22#include <assert.h>
23#include <errno.h>
87d1515d 24#include <string.h>
9152c765
LP
25#include <sys/epoll.h>
26#include <signal.h>
27#include <sys/signalfd.h>
28#include <sys/wait.h>
29#include <unistd.h>
30#include <sys/poll.h>
e1414003
LP
31#include <sys/reboot.h>
32#include <sys/ioctl.h>
33#include <linux/kd.h>
80876c20
LP
34#include <termios.h>
35#include <fcntl.h>
a16e1123
LP
36#include <sys/types.h>
37#include <sys/stat.h>
fe51822e 38#include <dirent.h>
830f6caa
LP
39
40#ifdef HAVE_AUDIT
4927fcae 41#include <libaudit.h>
830f6caa 42#endif
60918275 43
81527be1
LP
44#include <systemd/sd-daemon.h>
45
60918275
LP
46#include "manager.h"
47#include "hashmap.h"
48#include "macro.h"
49#include "strv.h"
16354eff 50#include "log.h"
2a987ee8 51#include "util.h"
ea430986 52#include "ratelimit.h"
8e274523
LP
53#include "cgroup.h"
54#include "mount-setup.h"
9e2f7c11 55#include "unit-name.h"
4139c1b2
LP
56#include "dbus-unit.h"
57#include "dbus-job.h"
1137a57c 58#include "missing.h"
84e3543e 59#include "path-lookup.h"
514f4ef5 60#include "special.h"
398ef8ba 61#include "bus-errors.h"
d06dacd0 62#include "exit-status.h"
5dc4c17f 63#include "virt.h"
60918275 64
701cc384
LP
65/* As soon as 16 units are in our GC queue, make sure to run a gc sweep */
66#define GC_QUEUE_ENTRIES_MAX 16
67
68/* As soon as 5s passed since a unit was added to our GC queue, make sure to run a gc sweep */
94b6dfa2 69#define GC_QUEUE_USEC_MAX (10*USEC_PER_SEC)
701cc384 70
8c47c732 71/* Where clients shall send notification messages to */
2b583ce6 72#define NOTIFY_SOCKET_SYSTEM "/run/systemd/notify"
91b22f21 73#define NOTIFY_SOCKET_USER "@/org/freedesktop/systemd1/notify"
8c47c732
LP
74
75static int manager_setup_notify(Manager *m) {
76 union {
77 struct sockaddr sa;
78 struct sockaddr_un un;
79 } sa;
80 struct epoll_event ev;
1d6702e8
LP
81 int one = 1, r;
82 mode_t u;
8c47c732
LP
83
84 assert(m);
85
86 m->notify_watch.type = WATCH_NOTIFY;
87 if ((m->notify_watch.fd = socket(AF_UNIX, SOCK_DGRAM|SOCK_CLOEXEC|SOCK_NONBLOCK, 0)) < 0) {
88 log_error("Failed to allocate notification socket: %m");
89 return -errno;
90 }
91
92 zero(sa);
93 sa.sa.sa_family = AF_UNIX;
94
a821caaa 95 if (getpid() != 1)
91b22f21 96 snprintf(sa.un.sun_path, sizeof(sa.un.sun_path), NOTIFY_SOCKET_USER "/%llu", random_ull());
6f79c579
LP
97 else {
98 unlink(NOTIFY_SOCKET_SYSTEM);
91b22f21 99 strncpy(sa.un.sun_path, NOTIFY_SOCKET_SYSTEM, sizeof(sa.un.sun_path));
6f79c579 100 }
91b22f21
LP
101
102 if (sa.un.sun_path[0] == '@')
103 sa.un.sun_path[0] = 0;
8c47c732 104
1d6702e8
LP
105 u = umask(0111);
106 r = bind(m->notify_watch.fd, &sa.sa, offsetof(struct sockaddr_un, sun_path) + 1 + strlen(sa.un.sun_path+1));
107 umask(u);
108
109 if (r < 0) {
8c47c732
LP
110 log_error("bind() failed: %m");
111 return -errno;
112 }
113
114 if (setsockopt(m->notify_watch.fd, SOL_SOCKET, SO_PASSCRED, &one, sizeof(one)) < 0) {
115 log_error("SO_PASSCRED failed: %m");
116 return -errno;
117 }
118
119 zero(ev);
120 ev.events = EPOLLIN;
121 ev.data.ptr = &m->notify_watch;
122
123 if (epoll_ctl(m->epoll_fd, EPOLL_CTL_ADD, m->notify_watch.fd, &ev) < 0)
124 return -errno;
125
91b22f21
LP
126 if (sa.un.sun_path[0] == 0)
127 sa.un.sun_path[0] = '@';
128
129 if (!(m->notify_socket = strdup(sa.un.sun_path)))
8c47c732
LP
130 return -ENOMEM;
131
b2bb3dbe
LP
132 log_debug("Using notification socket %s", m->notify_socket);
133
8c47c732
LP
134 return 0;
135}
136
80876c20 137static int enable_special_signals(Manager *m) {
4466ee6a 138 int fd;
80876c20
LP
139
140 assert(m);
141
142 /* Enable that we get SIGINT on control-alt-del */
143 if (reboot(RB_DISABLE_CAD) < 0)
144 log_warning("Failed to enable ctrl-alt-del handling: %m");
145
ccaa6149 146 if ((fd = open_terminal("/dev/tty0", O_RDWR|O_NOCTTY|O_CLOEXEC)) < 0)
80876c20
LP
147 log_warning("Failed to open /dev/tty0: %m");
148 else {
149 /* Enable that we get SIGWINCH on kbrequest */
150 if (ioctl(fd, KDSIGACCEPT, SIGWINCH) < 0)
151 log_warning("Failed to enable kbrequest handling: %s", strerror(errno));
152
153 close_nointr_nofail(fd);
154 }
155
156 return 0;
157}
158
ce578209 159static int manager_setup_signals(Manager *m) {
9152c765
LP
160 sigset_t mask;
161 struct epoll_event ev;
57c0c30e 162 struct sigaction sa;
60918275 163
ce578209
LP
164 assert(m);
165
57c0c30e
LP
166 /* We are not interested in SIGSTOP and friends. */
167 zero(sa);
168 sa.sa_handler = SIG_DFL;
169 sa.sa_flags = SA_NOCLDSTOP|SA_RESTART;
170 assert_se(sigaction(SIGCHLD, &sa, NULL) == 0);
171
ce578209 172 assert_se(sigemptyset(&mask) == 0);
7d793605
LP
173
174 sigset_add_many(&mask,
175 SIGCHLD, /* Child died */
176 SIGTERM, /* Reexecute daemon */
177 SIGHUP, /* Reload configuration */
178 SIGUSR1, /* systemd/upstart: reconnect to D-Bus */
179 SIGUSR2, /* systemd: dump status */
180 SIGINT, /* Kernel sends us this on control-alt-del */
181 SIGWINCH, /* Kernel sends us this on kbrequest (alt-arrowup) */
182 SIGPWR, /* Some kernel drivers and upsd send us this on power failure */
183 SIGRTMIN+0, /* systemd: start default.target */
0003d1ab 184 SIGRTMIN+1, /* systemd: isolate rescue.target */
7d793605
LP
185 SIGRTMIN+2, /* systemd: isolate emergency.target */
186 SIGRTMIN+3, /* systemd: start halt.target */
187 SIGRTMIN+4, /* systemd: start poweroff.target */
188 SIGRTMIN+5, /* systemd: start reboot.target */
0003d1ab
LP
189 SIGRTMIN+6, /* systemd: start kexec.target */
190 SIGRTMIN+13, /* systemd: Immediate halt */
191 SIGRTMIN+14, /* systemd: Immediate poweroff */
192 SIGRTMIN+15, /* systemd: Immediate reboot */
193 SIGRTMIN+16, /* systemd: Immediate kexec */
0658666b
LP
194 SIGRTMIN+20, /* systemd: enable status messages */
195 SIGRTMIN+21, /* systemd: disable status messages */
253ee27a
LP
196 SIGRTMIN+22, /* systemd: set log level to LOG_DEBUG */
197 SIGRTMIN+23, /* systemd: set log level to LOG_INFO */
198 SIGRTMIN+27, /* systemd: set log target to console */
199 SIGRTMIN+28, /* systemd: set log target to kmsg */
200 SIGRTMIN+29, /* systemd: set log target to syslog-or-kmsg */
7d793605 201 -1);
ce578209
LP
202 assert_se(sigprocmask(SIG_SETMASK, &mask, NULL) == 0);
203
ef734fd6 204 m->signal_watch.type = WATCH_SIGNAL;
ce578209
LP
205 if ((m->signal_watch.fd = signalfd(-1, &mask, SFD_NONBLOCK|SFD_CLOEXEC)) < 0)
206 return -errno;
207
208 zero(ev);
209 ev.events = EPOLLIN;
210 ev.data.ptr = &m->signal_watch;
211
212 if (epoll_ctl(m->epoll_fd, EPOLL_CTL_ADD, m->signal_watch.fd, &ev) < 0)
213 return -errno;
214
a3d4e06d 215 if (m->running_as == MANAGER_SYSTEM)
80876c20 216 return enable_special_signals(m);
e1414003 217
ce578209
LP
218 return 0;
219}
220
9e58ff9c 221int manager_new(ManagerRunningAs running_as, Manager **_m) {
ce578209 222 Manager *m;
8e274523
LP
223 int r = -ENOMEM;
224
225 assert(_m);
a5dab5ce
LP
226 assert(running_as >= 0);
227 assert(running_as < _MANAGER_RUNNING_AS_MAX);
ce578209 228
60918275 229 if (!(m = new0(Manager, 1)))
8e274523 230 return -ENOMEM;
60918275 231
63983207 232 dual_timestamp_get(&m->startup_timestamp);
e537352b 233
a5dab5ce 234 m->running_as = running_as;
cbd37330 235 m->name_data_slot = m->conn_data_slot = m->subscribed_data_slot = -1;
a16e1123 236 m->exit_code = _MANAGER_EXIT_CODE_INVALID;
33be102a 237 m->pin_cgroupfs_fd = -1;
80876c20 238
4927fcae
LP
239#ifdef HAVE_AUDIT
240 m->audit_fd = -1;
241#endif
242
4e434314 243 m->signal_watch.fd = m->mount_watch.fd = m->udev_watch.fd = m->epoll_fd = m->dev_autofs_fd = m->swap_watch.fd = -1;
ea430986 244 m->current_job_id = 1; /* start as id #1, so that we can leave #0 around as "null-like" value */
9152c765 245
1137a57c
LP
246 if (!(m->environment = strv_copy(environ)))
247 goto fail;
248
06d4c99a
LP
249 if (!(m->default_controllers = strv_new("cpu", NULL)))
250 goto fail;
251
87f0e418 252 if (!(m->units = hashmap_new(string_hash_func, string_compare_func)))
60918275
LP
253 goto fail;
254
255 if (!(m->jobs = hashmap_new(trivial_hash_func, trivial_compare_func)))
256 goto fail;
257
e5b5ae50 258 if (!(m->transaction_jobs = hashmap_new(trivial_hash_func, trivial_compare_func)))
60918275
LP
259 goto fail;
260
9152c765
LP
261 if (!(m->watch_pids = hashmap_new(trivial_hash_func, trivial_compare_func)))
262 goto fail;
263
8e274523
LP
264 if (!(m->cgroup_bondings = hashmap_new(string_hash_func, string_compare_func)))
265 goto fail;
266
05e343b7
LP
267 if (!(m->watch_bus = hashmap_new(string_hash_func, string_compare_func)))
268 goto fail;
269
9152c765
LP
270 if ((m->epoll_fd = epoll_create1(EPOLL_CLOEXEC)) < 0)
271 goto fail;
272
c800e483 273 if ((r = lookup_paths_init(&m->lookup_paths, m->running_as, true)) < 0)
e1414003
LP
274 goto fail;
275
8e274523
LP
276 if ((r = manager_setup_signals(m)) < 0)
277 goto fail;
278
8e274523 279 if ((r = manager_setup_cgroup(m)) < 0)
9152c765
LP
280 goto fail;
281
8c47c732
LP
282 if ((r = manager_setup_notify(m)) < 0)
283 goto fail;
284
f278026d 285 /* Try to connect to the busses, if possible. */
3996fbe2 286 if ((r = bus_init(m, running_as != MANAGER_SYSTEM)) < 0)
ea430986
LP
287 goto fail;
288
e543deae 289#ifdef HAVE_AUDIT
5a8d081c
JN
290 if ((m->audit_fd = audit_open()) < 0 &&
291 /* If the kernel lacks netlink or audit support,
292 * don't worry about it. */
293 errno != EAFNOSUPPORT && errno != EPROTONOSUPPORT)
4927fcae 294 log_error("Failed to connect to audit log: %m");
e543deae 295#endif
4927fcae 296
72bc8d00
LP
297 m->taint_usr = dir_is_empty("/usr") > 0;
298
8e274523
LP
299 *_m = m;
300 return 0;
60918275
LP
301
302fail:
303 manager_free(m);
8e274523 304 return r;
60918275
LP
305}
306
23a177ef
LP
307static unsigned manager_dispatch_cleanup_queue(Manager *m) {
308 Meta *meta;
309 unsigned n = 0;
310
311 assert(m);
312
313 while ((meta = m->cleanup_queue)) {
314 assert(meta->in_cleanup_queue);
315
399ab2b1 316 unit_free((Unit*) meta);
23a177ef
LP
317 n++;
318 }
319
320 return n;
321}
322
eced69b3 323enum {
35b8ca3a 324 GC_OFFSET_IN_PATH, /* This one is on the path we were traveling */
eced69b3
LP
325 GC_OFFSET_UNSURE, /* No clue */
326 GC_OFFSET_GOOD, /* We still need this unit */
327 GC_OFFSET_BAD, /* We don't need this unit anymore */
328 _GC_OFFSET_MAX
329};
330
331static void unit_gc_sweep(Unit *u, unsigned gc_marker) {
701cc384
LP
332 Iterator i;
333 Unit *other;
eced69b3 334 bool is_bad;
701cc384
LP
335
336 assert(u);
337
eced69b3
LP
338 if (u->meta.gc_marker == gc_marker + GC_OFFSET_GOOD ||
339 u->meta.gc_marker == gc_marker + GC_OFFSET_BAD ||
340 u->meta.gc_marker == gc_marker + GC_OFFSET_IN_PATH)
701cc384
LP
341 return;
342
c9c0cadb 343 if (u->meta.in_cleanup_queue)
701cc384
LP
344 goto bad;
345
346 if (unit_check_gc(u))
347 goto good;
348
eced69b3
LP
349 u->meta.gc_marker = gc_marker + GC_OFFSET_IN_PATH;
350
351 is_bad = true;
352
701cc384
LP
353 SET_FOREACH(other, u->meta.dependencies[UNIT_REFERENCED_BY], i) {
354 unit_gc_sweep(other, gc_marker);
355
eced69b3 356 if (other->meta.gc_marker == gc_marker + GC_OFFSET_GOOD)
701cc384 357 goto good;
eced69b3
LP
358
359 if (other->meta.gc_marker != gc_marker + GC_OFFSET_BAD)
360 is_bad = false;
701cc384
LP
361 }
362
eced69b3
LP
363 if (is_bad)
364 goto bad;
365
366 /* We were unable to find anything out about this entry, so
367 * let's investigate it later */
368 u->meta.gc_marker = gc_marker + GC_OFFSET_UNSURE;
369 unit_add_to_gc_queue(u);
370 return;
371
701cc384 372bad:
eced69b3
LP
373 /* We definitely know that this one is not useful anymore, so
374 * let's mark it for deletion */
375 u->meta.gc_marker = gc_marker + GC_OFFSET_BAD;
376 unit_add_to_cleanup_queue(u);
701cc384
LP
377 return;
378
379good:
eced69b3 380 u->meta.gc_marker = gc_marker + GC_OFFSET_GOOD;
701cc384
LP
381}
382
383static unsigned manager_dispatch_gc_queue(Manager *m) {
384 Meta *meta;
385 unsigned n = 0;
eced69b3 386 unsigned gc_marker;
701cc384
LP
387
388 assert(m);
389
390 if ((m->n_in_gc_queue < GC_QUEUE_ENTRIES_MAX) &&
391 (m->gc_queue_timestamp <= 0 ||
392 (m->gc_queue_timestamp + GC_QUEUE_USEC_MAX) > now(CLOCK_MONOTONIC)))
393 return 0;
394
395 log_debug("Running GC...");
396
eced69b3
LP
397 m->gc_marker += _GC_OFFSET_MAX;
398 if (m->gc_marker + _GC_OFFSET_MAX <= _GC_OFFSET_MAX)
c9c0cadb 399 m->gc_marker = 1;
701cc384 400
eced69b3
LP
401 gc_marker = m->gc_marker;
402
701cc384
LP
403 while ((meta = m->gc_queue)) {
404 assert(meta->in_gc_queue);
405
399ab2b1 406 unit_gc_sweep((Unit*) meta, gc_marker);
eced69b3 407
701cc384
LP
408 LIST_REMOVE(Meta, gc_queue, m->gc_queue, meta);
409 meta->in_gc_queue = false;
410
411 n++;
412
eced69b3
LP
413 if (meta->gc_marker == gc_marker + GC_OFFSET_BAD ||
414 meta->gc_marker == gc_marker + GC_OFFSET_UNSURE) {
701cc384 415 log_debug("Collecting %s", meta->id);
eced69b3 416 meta->gc_marker = gc_marker + GC_OFFSET_BAD;
399ab2b1 417 unit_add_to_cleanup_queue((Unit*) meta);
701cc384
LP
418 }
419 }
420
421 m->n_in_gc_queue = 0;
422 m->gc_queue_timestamp = 0;
423
424 return n;
425}
426
a16e1123 427static void manager_clear_jobs_and_units(Manager *m) {
e5b5ae50 428 Job *j;
a16e1123 429 Unit *u;
60918275
LP
430
431 assert(m);
432
87f0e418 433 while ((j = hashmap_first(m->transaction_jobs)))
e5b5ae50
LP
434 job_free(j);
435
87f0e418
LP
436 while ((u = hashmap_first(m->units)))
437 unit_free(u);
964e0949
LP
438
439 manager_dispatch_cleanup_queue(m);
440
441 assert(!m->load_queue);
442 assert(!m->run_queue);
443 assert(!m->dbus_unit_queue);
444 assert(!m->dbus_job_queue);
445 assert(!m->cleanup_queue);
446 assert(!m->gc_queue);
447
448 assert(hashmap_isempty(m->transaction_jobs));
449 assert(hashmap_isempty(m->jobs));
450 assert(hashmap_isempty(m->units));
a16e1123
LP
451}
452
453void manager_free(Manager *m) {
454 UnitType c;
87f0e418 455
a16e1123
LP
456 assert(m);
457
458 manager_clear_jobs_and_units(m);
23a177ef 459
7824bbeb
LP
460 for (c = 0; c < _UNIT_TYPE_MAX; c++)
461 if (unit_vtable[c]->shutdown)
462 unit_vtable[c]->shutdown(m);
463
a16e1123
LP
464 /* If we reexecute ourselves, we keep the root cgroup
465 * around */
c6c18be3 466 manager_shutdown_cgroup(m, m->exit_code != MANAGER_REEXECUTE);
8e274523 467
5a1e9937
LP
468 manager_undo_generators(m);
469
5e8d1c9a 470 bus_done(m);
ea430986 471
87f0e418 472 hashmap_free(m->units);
60918275 473 hashmap_free(m->jobs);
e5b5ae50 474 hashmap_free(m->transaction_jobs);
9152c765 475 hashmap_free(m->watch_pids);
05e343b7 476 hashmap_free(m->watch_bus);
9152c765
LP
477
478 if (m->epoll_fd >= 0)
a16e1123 479 close_nointr_nofail(m->epoll_fd);
acbb0225 480 if (m->signal_watch.fd >= 0)
a16e1123 481 close_nointr_nofail(m->signal_watch.fd);
8c47c732
LP
482 if (m->notify_watch.fd >= 0)
483 close_nointr_nofail(m->notify_watch.fd);
60918275 484
4927fcae
LP
485#ifdef HAVE_AUDIT
486 if (m->audit_fd >= 0)
487 audit_close(m->audit_fd);
488#endif
489
c952c6ec
LP
490 free(m->notify_socket);
491
84e3543e 492 lookup_paths_free(&m->lookup_paths);
1137a57c 493 strv_free(m->environment);
036643a2 494
06d4c99a
LP
495 strv_free(m->default_controllers);
496
8e274523 497 hashmap_free(m->cgroup_bondings);
c6c18be3 498 set_free_free(m->unit_path_cache);
33be102a 499
60918275
LP
500 free(m);
501}
502
a16e1123
LP
503int manager_enumerate(Manager *m) {
504 int r = 0, q;
f50e0a01 505 UnitType c;
f50e0a01
LP
506
507 assert(m);
508
a16e1123
LP
509 /* Let's ask every type to load all units from disk/kernel
510 * that it might know */
f50e0a01
LP
511 for (c = 0; c < _UNIT_TYPE_MAX; c++)
512 if (unit_vtable[c]->enumerate)
a16e1123
LP
513 if ((q = unit_vtable[c]->enumerate(m)) < 0)
514 r = q;
f50e0a01
LP
515
516 manager_dispatch_load_queue(m);
a16e1123
LP
517 return r;
518}
519
520int manager_coldplug(Manager *m) {
521 int r = 0, q;
522 Iterator i;
523 Unit *u;
524 char *k;
525
526 assert(m);
f50e0a01
LP
527
528 /* Then, let's set up their initial state. */
529 HASHMAP_FOREACH_KEY(u, k, m->units, i) {
530
531 /* ignore aliases */
9e2f7c11 532 if (u->meta.id != k)
f50e0a01
LP
533 continue;
534
cca098b0
LP
535 if ((q = unit_coldplug(u)) < 0)
536 r = q;
f50e0a01
LP
537 }
538
a16e1123
LP
539 return r;
540}
541
fe51822e
LP
542static void manager_build_unit_path_cache(Manager *m) {
543 char **i;
544 DIR *d = NULL;
545 int r;
546
547 assert(m);
548
549 set_free_free(m->unit_path_cache);
550
551 if (!(m->unit_path_cache = set_new(string_hash_func, string_compare_func))) {
552 log_error("Failed to allocate unit path cache.");
553 return;
554 }
555
556 /* This simply builds a list of files we know exist, so that
557 * we don't always have to go to disk */
558
559 STRV_FOREACH(i, m->lookup_paths.unit_path) {
560 struct dirent *de;
561
562 if (!(d = opendir(*i))) {
563 log_error("Failed to open directory: %m");
564 continue;
565 }
566
567 while ((de = readdir(d))) {
568 char *p;
569
570 if (ignore_file(de->d_name))
571 continue;
572
44d91056
LP
573 p = join(streq(*i, "/") ? "" : *i, "/", de->d_name, NULL);
574 if (!p) {
fe51822e
LP
575 r = -ENOMEM;
576 goto fail;
577 }
578
579 if ((r = set_put(m->unit_path_cache, p)) < 0) {
580 free(p);
581 goto fail;
582 }
583 }
584
585 closedir(d);
586 d = NULL;
587 }
588
589 return;
590
591fail:
592 log_error("Failed to build unit path cache: %s", strerror(-r));
593
594 set_free_free(m->unit_path_cache);
595 m->unit_path_cache = NULL;
596
597 if (d)
598 closedir(d);
599}
600
a16e1123
LP
601int manager_startup(Manager *m, FILE *serialization, FDSet *fds) {
602 int r, q;
603
604 assert(m);
605
5a1e9937
LP
606 manager_run_generators(m);
607
fe51822e
LP
608 manager_build_unit_path_cache(m);
609
9f611ad8
LP
610 /* If we will deserialize make sure that during enumeration
611 * this is already known, so we increase the counter here
612 * already */
613 if (serialization)
a7556052 614 m->n_reloading ++;
9f611ad8 615
a16e1123
LP
616 /* First, enumerate what we can from all config files */
617 r = manager_enumerate(m);
618
619 /* Second, deserialize if there is something to deserialize */
620 if (serialization)
621 if ((q = manager_deserialize(m, serialization, fds)) < 0)
622 r = q;
623
624 /* Third, fire things up! */
625 if ((q = manager_coldplug(m)) < 0)
626 r = q;
627
9f611ad8 628 if (serialization) {
a7556052
LP
629 assert(m->n_reloading > 0);
630 m->n_reloading --;
9f611ad8
LP
631 }
632
a16e1123 633 return r;
f50e0a01
LP
634}
635
23a177ef 636static void transaction_delete_job(Manager *m, Job *j, bool delete_dependencies) {
302d0040
LP
637 assert(m);
638 assert(j);
639
1ffba6fe
LP
640 /* Deletes one job from the transaction */
641
23a177ef 642 manager_transaction_unlink_job(m, j, delete_dependencies);
302d0040 643
ac1135be 644 if (!j->installed)
302d0040
LP
645 job_free(j);
646}
647
87f0e418 648static void transaction_delete_unit(Manager *m, Unit *u) {
1ffba6fe
LP
649 Job *j;
650
87f0e418 651 /* Deletes all jobs associated with a certain unit from the
1ffba6fe
LP
652 * transaction */
653
87f0e418 654 while ((j = hashmap_get(m->transaction_jobs, u)))
23a177ef 655 transaction_delete_job(m, j, true);
1ffba6fe
LP
656}
657
f04fa1d5
LP
658static void transaction_clean_dependencies(Manager *m) {
659 Iterator i;
660 Job *j;
661
662 assert(m);
663
664 /* Drops all dependencies of all installed jobs */
665
666 HASHMAP_FOREACH(j, m->jobs, i) {
667 while (j->subject_list)
668 job_dependency_free(j->subject_list);
669 while (j->object_list)
670 job_dependency_free(j->object_list);
671 }
672
673 assert(!m->transaction_anchor);
674}
675
11dd41ce
LP
676static void transaction_abort(Manager *m) {
677 Job *j;
678
679 assert(m);
11dd41ce 680
e5b5ae50 681 while ((j = hashmap_first(m->transaction_jobs)))
ac1135be 682 if (j->installed)
23a177ef 683 transaction_delete_job(m, j, true);
e5b5ae50
LP
684 else
685 job_free(j);
686
687 assert(hashmap_isempty(m->transaction_jobs));
f04fa1d5
LP
688
689 transaction_clean_dependencies(m);
e5b5ae50
LP
690}
691
692static void transaction_find_jobs_that_matter_to_anchor(Manager *m, Job *j, unsigned generation) {
693 JobDependency *l;
694
695 assert(m);
696
87f0e418 697 /* A recursive sweep through the graph that marks all units
1ffba6fe
LP
698 * that matter to the anchor job, i.e. are directly or
699 * indirectly a dependency of the anchor job via paths that
700 * are fully marked as mattering. */
701
44d8db9e
LP
702 if (j)
703 l = j->subject_list;
704 else
705 l = m->transaction_anchor;
706
707 LIST_FOREACH(subject, l, l) {
e5b5ae50
LP
708
709 /* This link does not matter */
710 if (!l->matters)
711 continue;
712
87f0e418 713 /* This unit has already been marked */
e5b5ae50
LP
714 if (l->object->generation == generation)
715 continue;
716
717 l->object->matters_to_anchor = true;
718 l->object->generation = generation;
719
720 transaction_find_jobs_that_matter_to_anchor(m, l->object, generation);
721 }
722}
723
7fad411c 724static void transaction_merge_and_delete_job(Manager *m, Job *j, Job *other, JobType t) {
e5b5ae50
LP
725 JobDependency *l, *last;
726
727 assert(j);
728 assert(other);
87f0e418 729 assert(j->unit == other->unit);
ac1135be 730 assert(!j->installed);
e5b5ae50 731
1ffba6fe
LP
732 /* Merges 'other' into 'j' and then deletes j. */
733
e5b5ae50
LP
734 j->type = t;
735 j->state = JOB_WAITING;
9e2f7c11 736 j->override = j->override || other->override;
e5b5ae50
LP
737
738 j->matters_to_anchor = j->matters_to_anchor || other->matters_to_anchor;
739
740 /* Patch us in as new owner of the JobDependency objects */
741 last = NULL;
44d8db9e 742 LIST_FOREACH(subject, l, other->subject_list) {
e5b5ae50
LP
743 assert(l->subject == other);
744 l->subject = j;
745 last = l;
746 }
747
748 /* Merge both lists */
749 if (last) {
750 last->subject_next = j->subject_list;
751 if (j->subject_list)
752 j->subject_list->subject_prev = last;
753 j->subject_list = other->subject_list;
754 }
755
756 /* Patch us in as new owner of the JobDependency objects */
757 last = NULL;
44d8db9e 758 LIST_FOREACH(object, l, other->object_list) {
e5b5ae50
LP
759 assert(l->object == other);
760 l->object = j;
761 last = l;
762 }
763
764 /* Merge both lists */
765 if (last) {
766 last->object_next = j->object_list;
767 if (j->object_list)
768 j->object_list->object_prev = last;
769 j->object_list = other->object_list;
770 }
771
e5b5ae50
LP
772 /* Kill the other job */
773 other->subject_list = NULL;
774 other->object_list = NULL;
23a177ef 775 transaction_delete_job(m, other, true);
e5b5ae50 776}
69dd2852
LP
777static bool job_is_conflicted_by(Job *j) {
778 JobDependency *l;
779
780 assert(j);
781
782 /* Returns true if this job is pulled in by a least one
783 * ConflictedBy dependency. */
784
785 LIST_FOREACH(object, l, j->object_list)
786 if (l->conflicts)
787 return true;
788
789 return false;
790}
e5b5ae50 791
5cb5a6ff 792static int delete_one_unmergeable_job(Manager *m, Job *j) {
1ffba6fe
LP
793 Job *k;
794
795 assert(j);
796
797 /* Tries to delete one item in the linked list
798 * j->transaction_next->transaction_next->... that conflicts
35b8ca3a 799 * with another one, in an attempt to make an inconsistent
1ffba6fe
LP
800 * transaction work. */
801
802 /* We rely here on the fact that if a merged with b does not
803 * merge with c, either a or b merge with c neither */
034c6ed7
LP
804 LIST_FOREACH(transaction, j, j)
805 LIST_FOREACH(transaction, k, j->transaction_next) {
1ffba6fe
LP
806 Job *d;
807
808 /* Is this one mergeable? Then skip it */
5cb5a6ff 809 if (job_type_is_mergeable(j->type, k->type))
1ffba6fe
LP
810 continue;
811
812 /* Ok, we found two that conflict, let's see if we can
813 * drop one of them */
69dd2852
LP
814 if (!j->matters_to_anchor && !k->matters_to_anchor) {
815
816 /* Both jobs don't matter, so let's
817 * find the one that is smarter to
818 * remove. Let's think positive and
819 * rather remove stops then starts --
820 * except if something is being
821 * stopped because it is conflicted by
822 * another unit in which case we
823 * rather remove the start. */
824
825 log_debug("Looking at job %s/%s conflicted_by=%s", j->unit->meta.id, job_type_to_string(j->type), yes_no(j->type == JOB_STOP && job_is_conflicted_by(j)));
826 log_debug("Looking at job %s/%s conflicted_by=%s", k->unit->meta.id, job_type_to_string(k->type), yes_no(k->type == JOB_STOP && job_is_conflicted_by(k)));
827
828 if (j->type == JOB_STOP) {
829
830 if (job_is_conflicted_by(j))
831 d = k;
832 else
833 d = j;
834
835 } else if (k->type == JOB_STOP) {
836
837 if (job_is_conflicted_by(k))
838 d = j;
839 else
840 d = k;
e364ad06
LP
841 } else
842 d = j;
69dd2852
LP
843
844 } else if (!j->matters_to_anchor)
1ffba6fe
LP
845 d = j;
846 else if (!k->matters_to_anchor)
847 d = k;
848 else
849 return -ENOEXEC;
850
851 /* Ok, we can drop one, so let's do so. */
2e81c8a5 852 log_debug("Fixing conflicting jobs by deleting job %s/%s", d->unit->meta.id, job_type_to_string(d->type));
23a177ef 853 transaction_delete_job(m, d, true);
1ffba6fe
LP
854 return 0;
855 }
856
857 return -EINVAL;
858}
859
398ef8ba 860static int transaction_merge_jobs(Manager *m, DBusError *e) {
11dd41ce 861 Job *j;
034c6ed7 862 Iterator i;
e5b5ae50
LP
863 int r;
864
865 assert(m);
866
1ffba6fe
LP
867 /* First step, check whether any of the jobs for one specific
868 * task conflict. If so, try to drop one of them. */
034c6ed7 869 HASHMAP_FOREACH(j, m->transaction_jobs, i) {
1ffba6fe
LP
870 JobType t;
871 Job *k;
872
873 t = j->type;
034c6ed7 874 LIST_FOREACH(transaction, k, j->transaction_next) {
e364ad06 875 if (job_type_merge(&t, k->type) >= 0)
1ffba6fe
LP
876 continue;
877
878 /* OK, we could not merge all jobs for this
879 * action. Let's see if we can get rid of one
880 * of them */
881
5cb5a6ff 882 if ((r = delete_one_unmergeable_job(m, j)) >= 0)
1ffba6fe
LP
883 /* Ok, we managed to drop one, now
884 * let's ask our callers to call us
885 * again after garbage collecting */
886 return -EAGAIN;
887
888 /* We couldn't merge anything. Failure */
398ef8ba
LP
889 dbus_set_error(e, BUS_ERROR_TRANSACTION_JOBS_CONFLICTING, "Transaction contains conflicting jobs '%s' and '%s' for %s. Probably contradicting requirement dependencies configured.",
890 job_type_to_string(t), job_type_to_string(k->type), k->unit->meta.id);
1ffba6fe
LP
891 return r;
892 }
893 }
894
895 /* Second step, merge the jobs. */
034c6ed7 896 HASHMAP_FOREACH(j, m->transaction_jobs, i) {
e5b5ae50
LP
897 JobType t = j->type;
898 Job *k;
899
e094e853 900 /* Merge all transactions */
034c6ed7 901 LIST_FOREACH(transaction, k, j->transaction_next)
1ffba6fe 902 assert_se(job_type_merge(&t, k->type) == 0);
e5b5ae50 903
5cb5a6ff 904 /* If an active job is mergeable, merge it too */
87f0e418
LP
905 if (j->unit->meta.job)
906 job_type_merge(&t, j->unit->meta.job->type); /* Might fail. Which is OK */
e094e853 907
e5b5ae50 908 while ((k = j->transaction_next)) {
ac1135be 909 if (j->installed) {
7fad411c 910 transaction_merge_and_delete_job(m, k, j, t);
e5b5ae50
LP
911 j = k;
912 } else
7fad411c 913 transaction_merge_and_delete_job(m, j, k, t);
e5b5ae50
LP
914 }
915
1b562e46
MS
916 if (j->unit->meta.job && !j->installed)
917 transaction_merge_and_delete_job(m, j, j->unit->meta.job, t);
918
e5b5ae50
LP
919 assert(!j->transaction_next);
920 assert(!j->transaction_prev);
921 }
922
7fad411c 923 return 0;
e5b5ae50
LP
924}
925
23a177ef
LP
926static void transaction_drop_redundant(Manager *m) {
927 bool again;
928
929 assert(m);
930
931 /* Goes through the transaction and removes all jobs that are
932 * a noop */
933
934 do {
935 Job *j;
936 Iterator i;
937
938 again = false;
939
940 HASHMAP_FOREACH(j, m->transaction_jobs, i) {
941 bool changes_something = false;
942 Job *k;
943
944 LIST_FOREACH(transaction, k, j) {
945
946 if (!job_is_anchor(k) &&
3aea3b35
LP
947 (k->installed || job_type_is_redundant(k->type, unit_active_state(k->unit))) &&
948 (!k->unit->meta.job || !job_type_is_conflicting(k->type, k->unit->meta.job->type)))
23a177ef
LP
949 continue;
950
951 changes_something = true;
952 break;
953 }
954
955 if (changes_something)
956 continue;
957
9b3d9090 958 /* log_debug("Found redundant job %s/%s, dropping.", j->unit->meta.id, job_type_to_string(j->type)); */
23a177ef
LP
959 transaction_delete_job(m, j, false);
960 again = true;
961 break;
962 }
963
964 } while (again);
965}
966
87f0e418
LP
967static bool unit_matters_to_anchor(Unit *u, Job *j) {
968 assert(u);
1ffba6fe
LP
969 assert(!j->transaction_prev);
970
87f0e418 971 /* Checks whether at least one of the jobs for this unit
1ffba6fe
LP
972 * matters to the anchor. */
973
034c6ed7 974 LIST_FOREACH(transaction, j, j)
1ffba6fe
LP
975 if (j->matters_to_anchor)
976 return true;
977
978 return false;
979}
980
398ef8ba 981static int transaction_verify_order_one(Manager *m, Job *j, Job *from, unsigned generation, DBusError *e) {
034c6ed7 982 Iterator i;
87f0e418 983 Unit *u;
11dd41ce 984 int r;
e5b5ae50
LP
985
986 assert(m);
987 assert(j);
1ffba6fe
LP
988 assert(!j->transaction_prev);
989
990 /* Does a recursive sweep through the ordering graph, looking
991 * for a cycle. If we find cycle we try to break it. */
e5b5ae50 992
23e3c588
LP
993 /* Have we seen this before? */
994 if (j->generation == generation) {
674a6e4d 995 Job *k, *delete;
e5b5ae50 996
23e3c588
LP
997 /* If the marker is NULL we have been here already and
998 * decided the job was loop-free from here. Hence
999 * shortcut things and return right-away. */
1000 if (!j->marker)
1001 return 0;
e5b5ae50 1002
23e3c588
LP
1003 /* So, the marker is not NULL and we already have been
1004 * here. We have a cycle. Let's try to break it. We go
1005 * backwards in our path and try to find a suitable
1006 * job to remove. We use the marker to find our way
1007 * back, since smart how we are we stored our way back
1008 * in there. */
54165a39 1009 log_warning("Found ordering cycle on %s/%s", j->unit->meta.id, job_type_to_string(j->type));
9f04bd52 1010
674a6e4d 1011 delete = NULL;
23e3c588 1012 for (k = from; k; k = ((k->generation == generation && k->marker != k) ? k->marker : NULL)) {
1ffba6fe 1013
54165a39 1014 log_info("Walked on cycle path to %s/%s", k->unit->meta.id, job_type_to_string(k->type));
9f04bd52 1015
674a6e4d
LP
1016 if (!delete &&
1017 !k->installed &&
87f0e418 1018 !unit_matters_to_anchor(k->unit, k)) {
1ffba6fe
LP
1019 /* Ok, we can drop this one, so let's
1020 * do so. */
674a6e4d 1021 delete = k;
e5b5ae50
LP
1022 }
1023
1024 /* Check if this in fact was the beginning of
7fad411c 1025 * the cycle */
e5b5ae50
LP
1026 if (k == j)
1027 break;
1028 }
1029
674a6e4d
LP
1030
1031 if (delete) {
54ec68b6 1032 log_warning("Breaking ordering cycle by deleting job %s/%s", delete->unit->meta.id, job_type_to_string(delete->type));
674a6e4d
LP
1033 transaction_delete_unit(m, delete->unit);
1034 return -EAGAIN;
1035 }
1036
54165a39 1037 log_error("Unable to break cycle");
9f04bd52 1038
fe71c02c 1039 dbus_set_error(e, BUS_ERROR_TRANSACTION_ORDER_IS_CYCLIC, "Transaction order is cyclic. See system logs for details.");
1ffba6fe 1040 return -ENOEXEC;
e5b5ae50
LP
1041 }
1042
1ffba6fe 1043 /* Make the marker point to where we come from, so that we can
23e3c588
LP
1044 * find our way backwards if we want to break a cycle. We use
1045 * a special marker for the beginning: we point to
1046 * ourselves. */
1047 j->marker = from ? from : j;
e5b5ae50
LP
1048 j->generation = generation;
1049
1ffba6fe 1050 /* We assume that the the dependencies are bidirectional, and
87f0e418
LP
1051 * hence can ignore UNIT_AFTER */
1052 SET_FOREACH(u, j->unit->meta.dependencies[UNIT_BEFORE], i) {
e5b5ae50
LP
1053 Job *o;
1054
87f0e418
LP
1055 /* Is there a job for this unit? */
1056 if (!(o = hashmap_get(m->transaction_jobs, u)))
1ffba6fe
LP
1057
1058 /* Ok, there is no job for this in the
1059 * transaction, but maybe there is already one
1060 * running? */
87f0e418 1061 if (!(o = u->meta.job))
e5b5ae50
LP
1062 continue;
1063
398ef8ba 1064 if ((r = transaction_verify_order_one(m, o, j, generation, e)) < 0)
e5b5ae50
LP
1065 return r;
1066 }
1067
9f04bd52
LP
1068 /* Ok, let's backtrack, and remember that this entry is not on
1069 * our path anymore. */
1070 j->marker = NULL;
1071
e5b5ae50
LP
1072 return 0;
1073}
1074
398ef8ba 1075static int transaction_verify_order(Manager *m, unsigned *generation, DBusError *e) {
1ffba6fe
LP
1076 Job *j;
1077 int r;
034c6ed7 1078 Iterator i;
23e3c588 1079 unsigned g;
1ffba6fe 1080
e5b5ae50
LP
1081 assert(m);
1082 assert(generation);
1083
1ffba6fe
LP
1084 /* Check if the ordering graph is cyclic. If it is, try to fix
1085 * that up by dropping one of the jobs. */
e5b5ae50 1086
23e3c588
LP
1087 g = (*generation)++;
1088
034c6ed7 1089 HASHMAP_FOREACH(j, m->transaction_jobs, i)
398ef8ba 1090 if ((r = transaction_verify_order_one(m, j, NULL, g, e)) < 0)
1ffba6fe 1091 return r;
e5b5ae50
LP
1092
1093 return 0;
1094}
1095
1096static void transaction_collect_garbage(Manager *m) {
1097 bool again;
1098
1099 assert(m);
1100
1ffba6fe
LP
1101 /* Drop jobs that are not required by any other job */
1102
e5b5ae50 1103 do {
034c6ed7 1104 Iterator i;
e5b5ae50
LP
1105 Job *j;
1106
1107 again = false;
1108
034c6ed7 1109 HASHMAP_FOREACH(j, m->transaction_jobs, i) {
9b3d9090
LP
1110 if (j->object_list) {
1111 /* log_debug("Keeping job %s/%s because of %s/%s", */
1112 /* j->unit->meta.id, job_type_to_string(j->type), */
1113 /* j->object_list->subject ? j->object_list->subject->unit->meta.id : "root", */
1114 /* j->object_list->subject ? job_type_to_string(j->object_list->subject->type) : "root"); */
e5b5ae50 1115 continue;
9b3d9090 1116 }
e5b5ae50 1117
9b3d9090 1118 /* log_debug("Garbage collecting job %s/%s", j->unit->meta.id, job_type_to_string(j->type)); */
23a177ef 1119 transaction_delete_job(m, j, true);
e5b5ae50
LP
1120 again = true;
1121 break;
1122 }
1123
1124 } while (again);
1125}
1126
398ef8ba 1127static int transaction_is_destructive(Manager *m, DBusError *e) {
034c6ed7 1128 Iterator i;
e5b5ae50 1129 Job *j;
11dd41ce
LP
1130
1131 assert(m);
11dd41ce 1132
e5b5ae50
LP
1133 /* Checks whether applying this transaction means that
1134 * existing jobs would be replaced */
11dd41ce 1135
034c6ed7 1136 HASHMAP_FOREACH(j, m->transaction_jobs, i) {
e094e853
LP
1137
1138 /* Assume merged */
1139 assert(!j->transaction_prev);
1140 assert(!j->transaction_next);
1141
87f0e418
LP
1142 if (j->unit->meta.job &&
1143 j->unit->meta.job != j &&
398ef8ba
LP
1144 !job_type_is_superset(j->type, j->unit->meta.job->type)) {
1145
1146 dbus_set_error(e, BUS_ERROR_TRANSACTION_IS_DESTRUCTIVE, "Transaction is destructive.");
e5b5ae50 1147 return -EEXIST;
398ef8ba 1148 }
e094e853 1149 }
11dd41ce 1150
e5b5ae50
LP
1151 return 0;
1152}
1153
e094e853
LP
1154static void transaction_minimize_impact(Manager *m) {
1155 bool again;
1156 assert(m);
1157
1158 /* Drops all unnecessary jobs that reverse already active jobs
1159 * or that stop a running service. */
1160
1161 do {
1162 Job *j;
034c6ed7 1163 Iterator i;
e094e853
LP
1164
1165 again = false;
1166
034c6ed7
LP
1167 HASHMAP_FOREACH(j, m->transaction_jobs, i) {
1168 LIST_FOREACH(transaction, j, j) {
c20cae32 1169 bool stops_running_service, changes_existing_job;
e094e853
LP
1170
1171 /* If it matters, we shouldn't drop it */
1172 if (j->matters_to_anchor)
1173 continue;
1174
1175 /* Would this stop a running service?
1176 * Would this change an existing job?
1177 * If so, let's drop this entry */
c20cae32
LP
1178
1179 stops_running_service =
1180 j->type == JOB_STOP && UNIT_IS_ACTIVE_OR_ACTIVATING(unit_active_state(j->unit));
1181
1182 changes_existing_job =
143072ed
LP
1183 j->unit->meta.job &&
1184 job_type_is_conflicting(j->type, j->unit->meta.job->type);
c20cae32
LP
1185
1186 if (!stops_running_service && !changes_existing_job)
e094e853
LP
1187 continue;
1188
c20cae32 1189 if (stops_running_service)
d718bbb5 1190 log_debug("%s/%s would stop a running service.", j->unit->meta.id, job_type_to_string(j->type));
c20cae32
LP
1191
1192 if (changes_existing_job)
d718bbb5 1193 log_debug("%s/%s would change existing job.", j->unit->meta.id, job_type_to_string(j->type));
c20cae32 1194
e094e853 1195 /* Ok, let's get rid of this */
d718bbb5 1196 log_debug("Deleting %s/%s to minimize impact.", j->unit->meta.id, job_type_to_string(j->type));
c20cae32 1197
23a177ef 1198 transaction_delete_job(m, j, true);
e094e853
LP
1199 again = true;
1200 break;
1201 }
1202
1203 if (again)
1204 break;
1205 }
1206
1207 } while (again);
1208}
1209
4fe60156 1210static int transaction_apply(Manager *m, JobMode mode) {
034c6ed7 1211 Iterator i;
e5b5ae50
LP
1212 Job *j;
1213 int r;
1214
1ffba6fe
LP
1215 /* Moves the transaction jobs to the set of active jobs */
1216
4fe60156
LP
1217 if (mode == JOB_ISOLATE) {
1218
1219 /* When isolating first kill all installed jobs which
1220 * aren't part of the new transaction */
563ba9ea 1221 rescan:
4fe60156
LP
1222 HASHMAP_FOREACH(j, m->jobs, i) {
1223 assert(j->installed);
1224
1225 if (hashmap_get(m->transaction_jobs, j->unit))
1226 continue;
1227
563ba9ea
MS
1228 /* 'j' itself is safe to remove, but if other jobs
1229 are invalidated recursively, our iterator may become
1230 invalid and we need to start over. */
1231 if (job_finish_and_invalidate(j, JOB_CANCELED) > 0)
1232 goto rescan;
4fe60156
LP
1233 }
1234 }
1235
034c6ed7 1236 HASHMAP_FOREACH(j, m->transaction_jobs, i) {
e094e853
LP
1237 /* Assume merged */
1238 assert(!j->transaction_prev);
1239 assert(!j->transaction_next);
1240
ac1135be 1241 if (j->installed)
e5b5ae50
LP
1242 continue;
1243
1244 if ((r = hashmap_put(m->jobs, UINT32_TO_PTR(j->id), j)) < 0)
11dd41ce
LP
1245 goto rollback;
1246 }
1247
e5b5ae50 1248 while ((j = hashmap_steal_first(m->transaction_jobs))) {
9b3d9090
LP
1249 if (j->installed) {
1250 /* log_debug("Skipping already installed job %s/%s as %u", j->unit->meta.id, job_type_to_string(j->type), (unsigned) j->id); */
e5b5ae50 1251 continue;
9b3d9090 1252 }
e5b5ae50 1253
87f0e418
LP
1254 if (j->unit->meta.job)
1255 job_free(j->unit->meta.job);
11dd41ce 1256
87f0e418 1257 j->unit->meta.job = j;
ac1135be 1258 j->installed = true;
e409f875 1259 m->n_installed_jobs ++;
11dd41ce 1260
e5b5ae50
LP
1261 /* We're fully installed. Now let's free data we don't
1262 * need anymore. */
1263
1264 assert(!j->transaction_next);
1265 assert(!j->transaction_prev);
1266
c1e1601e
LP
1267 job_add_to_run_queue(j);
1268 job_add_to_dbus_queue(j);
312732cf 1269 job_start_timer(j);
28c3247e
LP
1270
1271 log_debug("Installed new job %s/%s as %u", j->unit->meta.id, job_type_to_string(j->type), (unsigned) j->id);
01184e04
LP
1272 }
1273
1274 /* As last step, kill all remaining job dependencies. */
f04fa1d5 1275 transaction_clean_dependencies(m);
1ffba6fe 1276
11dd41ce
LP
1277 return 0;
1278
1279rollback:
1280
034c6ed7 1281 HASHMAP_FOREACH(j, m->transaction_jobs, i) {
ac1135be 1282 if (j->installed)
e5b5ae50
LP
1283 continue;
1284
1285 hashmap_remove(m->jobs, UINT32_TO_PTR(j->id));
1286 }
1287
1288 return r;
1289}
1290
398ef8ba 1291static int transaction_activate(Manager *m, JobMode mode, DBusError *e) {
e5b5ae50
LP
1292 int r;
1293 unsigned generation = 1;
1294
1295 assert(m);
1296
1297 /* This applies the changes recorded in transaction_jobs to
1298 * the actual list of jobs, if possible. */
1299
1300 /* First step: figure out which jobs matter */
1301 transaction_find_jobs_that_matter_to_anchor(m, NULL, generation++);
1302
e094e853
LP
1303 /* Second step: Try not to stop any running services if
1304 * we don't have to. Don't try to reverse running
1305 * jobs if we don't have to. */
143072ed 1306 if (mode == JOB_FAIL)
c88e7f4e 1307 transaction_minimize_impact(m);
e094e853 1308
23a177ef
LP
1309 /* Third step: Drop redundant jobs */
1310 transaction_drop_redundant(m);
1311
1ffba6fe 1312 for (;;) {
23a177ef 1313 /* Fourth step: Let's remove unneeded jobs that might
1ffba6fe 1314 * be lurking. */
a8049b7a
LP
1315 if (mode != JOB_ISOLATE)
1316 transaction_collect_garbage(m);
e5b5ae50 1317
23a177ef 1318 /* Fifth step: verify order makes sense and correct
1ffba6fe 1319 * cycles if necessary and possible */
398ef8ba 1320 if ((r = transaction_verify_order(m, &generation, e)) >= 0)
1ffba6fe 1321 break;
e5b5ae50 1322
9f04bd52 1323 if (r != -EAGAIN) {
398ef8ba 1324 log_warning("Requested transaction contains an unfixable cyclic ordering dependency: %s", bus_error(e, r));
1ffba6fe 1325 goto rollback;
9f04bd52 1326 }
e5b5ae50 1327
1ffba6fe
LP
1328 /* Let's see if the resulting transaction ordering
1329 * graph is still cyclic... */
1330 }
1331
1332 for (;;) {
23a177ef 1333 /* Sixth step: let's drop unmergeable entries if
1ffba6fe
LP
1334 * necessary and possible, merge entries we can
1335 * merge */
398ef8ba 1336 if ((r = transaction_merge_jobs(m, e)) >= 0)
1ffba6fe
LP
1337 break;
1338
9f04bd52 1339 if (r != -EAGAIN) {
35b8ca3a 1340 log_warning("Requested transaction contains unmergeable jobs: %s", bus_error(e, r));
1ffba6fe 1341 goto rollback;
9f04bd52 1342 }
1ffba6fe 1343
23a177ef 1344 /* Seventh step: an entry got dropped, let's garbage
1ffba6fe 1345 * collect its dependencies. */
a8049b7a
LP
1346 if (mode != JOB_ISOLATE)
1347 transaction_collect_garbage(m);
1ffba6fe
LP
1348
1349 /* Let's see if the resulting transaction still has
5cb5a6ff 1350 * unmergeable entries ... */
1ffba6fe
LP
1351 }
1352
23a177ef
LP
1353 /* Eights step: Drop redundant jobs again, if the merging now allows us to drop more. */
1354 transaction_drop_redundant(m);
1355
1356 /* Ninth step: check whether we can actually apply this */
e5b5ae50 1357 if (mode == JOB_FAIL)
398ef8ba
LP
1358 if ((r = transaction_is_destructive(m, e)) < 0) {
1359 log_notice("Requested transaction contradicts existing jobs: %s", bus_error(e, r));
e5b5ae50 1360 goto rollback;
9f04bd52 1361 }
e5b5ae50 1362
23a177ef 1363 /* Tenth step: apply changes */
4fe60156 1364 if ((r = transaction_apply(m, mode)) < 0) {
54165a39 1365 log_warning("Failed to apply transaction: %s", strerror(-r));
e5b5ae50 1366 goto rollback;
9f04bd52 1367 }
e5b5ae50
LP
1368
1369 assert(hashmap_isempty(m->transaction_jobs));
1370 assert(!m->transaction_anchor);
1371
1372 return 0;
11dd41ce 1373
e5b5ae50 1374rollback:
11dd41ce
LP
1375 transaction_abort(m);
1376 return r;
1377}
1378
9e2f7c11 1379static Job* transaction_add_one_job(Manager *m, JobType type, Unit *unit, bool override, bool *is_new) {
e5b5ae50 1380 Job *j, *f;
60918275
LP
1381
1382 assert(m);
87f0e418 1383 assert(unit);
60918275 1384
35b8ca3a 1385 /* Looks for an existing prospective job and returns that. If
e5b5ae50
LP
1386 * it doesn't exist it is created and added to the prospective
1387 * jobs list. */
60918275 1388
87f0e418 1389 f = hashmap_get(m->transaction_jobs, unit);
60918275 1390
034c6ed7 1391 LIST_FOREACH(transaction, j, f) {
87f0e418 1392 assert(j->unit == unit);
60918275 1393
e5b5ae50
LP
1394 if (j->type == type) {
1395 if (is_new)
1396 *is_new = false;
1397 return j;
1398 }
1399 }
60918275 1400
87f0e418
LP
1401 if (unit->meta.job && unit->meta.job->type == type)
1402 j = unit->meta.job;
1403 else if (!(j = job_new(m, type, unit)))
e5b5ae50 1404 return NULL;
60918275 1405
e5b5ae50
LP
1406 j->generation = 0;
1407 j->marker = NULL;
1408 j->matters_to_anchor = false;
9e2f7c11 1409 j->override = override;
60918275 1410
034c6ed7
LP
1411 LIST_PREPEND(Job, transaction, f, j);
1412
e364ad06 1413 if (hashmap_replace(m->transaction_jobs, unit, f) < 0) {
034c6ed7
LP
1414 job_free(j);
1415 return NULL;
1416 }
1417
e5b5ae50
LP
1418 if (is_new)
1419 *is_new = true;
60918275 1420
9b3d9090 1421 /* log_debug("Added job %s/%s to transaction.", unit->meta.id, job_type_to_string(type)); */
23a177ef 1422
e5b5ae50
LP
1423 return j;
1424}
11dd41ce 1425
23a177ef 1426void manager_transaction_unlink_job(Manager *m, Job *j, bool delete_dependencies) {
e5b5ae50
LP
1427 assert(m);
1428 assert(j);
11dd41ce 1429
e5b5ae50
LP
1430 if (j->transaction_prev)
1431 j->transaction_prev->transaction_next = j->transaction_next;
1432 else if (j->transaction_next)
87f0e418 1433 hashmap_replace(m->transaction_jobs, j->unit, j->transaction_next);
e5b5ae50 1434 else
87f0e418 1435 hashmap_remove_value(m->transaction_jobs, j->unit, j);
e5b5ae50
LP
1436
1437 if (j->transaction_next)
1438 j->transaction_next->transaction_prev = j->transaction_prev;
1439
1440 j->transaction_prev = j->transaction_next = NULL;
1441
1442 while (j->subject_list)
1443 job_dependency_free(j->subject_list);
1e198baf
LP
1444
1445 while (j->object_list) {
1446 Job *other = j->object_list->matters ? j->object_list->subject : NULL;
1447
e5b5ae50 1448 job_dependency_free(j->object_list);
1e198baf 1449
23a177ef 1450 if (other && delete_dependencies) {
2e81c8a5 1451 log_debug("Deleting job %s/%s as dependency of job %s/%s",
9e2f7c11
LP
1452 other->unit->meta.id, job_type_to_string(other->type),
1453 j->unit->meta.id, job_type_to_string(j->type));
23a177ef 1454 transaction_delete_job(m, other, delete_dependencies);
1e198baf
LP
1455 }
1456 }
e5b5ae50
LP
1457}
1458
9e2f7c11
LP
1459static int transaction_add_job_and_dependencies(
1460 Manager *m,
1461 JobType type,
1462 Unit *unit,
1463 Job *by,
1464 bool matters,
1465 bool override,
69dd2852 1466 bool conflicts,
cebe0d41
LP
1467 bool ignore_requirements,
1468 bool ignore_order,
398ef8ba 1469 DBusError *e,
9e2f7c11 1470 Job **_ret) {
e5b5ae50 1471 Job *ret;
034c6ed7 1472 Iterator i;
87f0e418 1473 Unit *dep;
e5b5ae50
LP
1474 int r;
1475 bool is_new;
1476
1477 assert(m);
1478 assert(type < _JOB_TYPE_MAX);
87f0e418 1479 assert(unit);
e5b5ae50 1480
3aea3b35
LP
1481 /* log_debug("Pulling in %s/%s from %s/%s", */
1482 /* unit->meta.id, job_type_to_string(type), */
1483 /* by ? by->unit->meta.id : "NA", */
1484 /* by ? job_type_to_string(by->type) : "NA"); */
1485
00dc5d76
LP
1486 if (unit->meta.load_state != UNIT_LOADED &&
1487 unit->meta.load_state != UNIT_ERROR &&
6daf4f90 1488 unit->meta.load_state != UNIT_MASKED) {
8821a00f
LP
1489 dbus_set_error(e, BUS_ERROR_LOAD_FAILED, "Unit %s is not loaded properly.", unit->meta.id);
1490 return -EINVAL;
1491 }
1492
fdf20a31 1493 if (type != JOB_STOP && unit->meta.load_state == UNIT_ERROR) {
00dc5d76
LP
1494 dbus_set_error(e, BUS_ERROR_LOAD_FAILED,
1495 "Unit %s failed to load: %s. "
3661ac04 1496 "See system logs and 'systemctl status %s' for details.",
8821a00f 1497 unit->meta.id,
3661ac04
LP
1498 strerror(-unit->meta.load_error),
1499 unit->meta.id);
21b293e8 1500 return -EINVAL;
398ef8ba 1501 }
21b293e8 1502
6daf4f90
LP
1503 if (type != JOB_STOP && unit->meta.load_state == UNIT_MASKED) {
1504 dbus_set_error(e, BUS_ERROR_MASKED, "Unit %s is masked.", unit->meta.id);
00dc5d76
LP
1505 return -EINVAL;
1506 }
1507
398ef8ba
LP
1508 if (!unit_job_is_applicable(unit, type)) {
1509 dbus_set_error(e, BUS_ERROR_JOB_TYPE_NOT_APPLICABLE, "Job type %s is not applicable for unit %s.", job_type_to_string(type), unit->meta.id);
cd2dbd7d 1510 return -EBADR;
398ef8ba 1511 }
cd2dbd7d 1512
e5b5ae50 1513 /* First add the job. */
9e2f7c11 1514 if (!(ret = transaction_add_one_job(m, type, unit, override, &is_new)))
e5b5ae50
LP
1515 return -ENOMEM;
1516
cebe0d41 1517 ret->ignore_order = ret->ignore_order || ignore_order;
e67c3609 1518
e5b5ae50 1519 /* Then, add a link to the job. */
69dd2852 1520 if (!job_dependency_new(by, ret, matters, conflicts))
e5b5ae50
LP
1521 return -ENOMEM;
1522
cebe0d41 1523 if (is_new && !ignore_requirements) {
6210e7fc
LP
1524 Set *following;
1525
1526 /* If we are following some other unit, make sure we
1527 * add all dependencies of everybody following. */
1528 if (unit_following_set(ret->unit, &following) > 0) {
1529 SET_FOREACH(dep, following, i)
cebe0d41 1530 if ((r = transaction_add_job_and_dependencies(m, type, dep, ret, false, override, false, false, ignore_order, e, NULL)) < 0) {
6210e7fc
LP
1531 log_warning("Cannot add dependency job for unit %s, ignoring: %s", dep->meta.id, bus_error(e, r));
1532
1533 if (e)
1534 dbus_error_free(e);
1535 }
1536
1537 set_free(following);
1538 }
1539
e5b5ae50
LP
1540 /* Finally, recursively add in all dependencies. */
1541 if (type == JOB_START || type == JOB_RELOAD_OR_START) {
87f0e418 1542 SET_FOREACH(dep, ret->unit->meta.dependencies[UNIT_REQUIRES], i)
cebe0d41 1543 if ((r = transaction_add_job_and_dependencies(m, JOB_START, dep, ret, true, override, false, false, ignore_order, e, NULL)) < 0) {
41242c42
LP
1544 if (r != -EBADR)
1545 goto fail;
1546
1547 if (e)
1548 dbus_error_free(e);
1549 }
9e2f7c11 1550
b81884e7 1551 SET_FOREACH(dep, ret->unit->meta.dependencies[UNIT_BIND_TO], i)
cebe0d41 1552 if ((r = transaction_add_job_and_dependencies(m, JOB_START, dep, ret, true, override, false, false, ignore_order, e, NULL)) < 0) {
41242c42
LP
1553
1554 if (r != -EBADR)
1555 goto fail;
1556
1557 if (e)
1558 dbus_error_free(e);
1559 }
b81884e7 1560
9e2f7c11 1561 SET_FOREACH(dep, ret->unit->meta.dependencies[UNIT_REQUIRES_OVERRIDABLE], i)
cebe0d41 1562 if ((r = transaction_add_job_and_dependencies(m, JOB_START, dep, ret, !override, override, false, false, ignore_order, e, NULL)) < 0) {
65e92d67 1563 log_warning("Cannot add dependency job for unit %s, ignoring: %s", dep->meta.id, bus_error(e, r));
60dc72b5
LP
1564
1565 if (e)
1566 dbus_error_free(e);
65e92d67 1567 }
9e2f7c11 1568
87f0e418 1569 SET_FOREACH(dep, ret->unit->meta.dependencies[UNIT_WANTS], i)
cebe0d41 1570 if ((r = transaction_add_job_and_dependencies(m, JOB_START, dep, ret, false, false, false, false, ignore_order, e, NULL)) < 0) {
65e92d67 1571 log_warning("Cannot add dependency job for unit %s, ignoring: %s", dep->meta.id, bus_error(e, r));
60dc72b5
LP
1572
1573 if (e)
1574 dbus_error_free(e);
65e92d67 1575 }
9e2f7c11 1576
87f0e418 1577 SET_FOREACH(dep, ret->unit->meta.dependencies[UNIT_REQUISITE], i)
cebe0d41 1578 if ((r = transaction_add_job_and_dependencies(m, JOB_VERIFY_ACTIVE, dep, ret, true, override, false, false, ignore_order, e, NULL)) < 0) {
41242c42
LP
1579
1580 if (r != -EBADR)
1581 goto fail;
1582
1583 if (e)
1584 dbus_error_free(e);
1585 }
9e2f7c11
LP
1586
1587 SET_FOREACH(dep, ret->unit->meta.dependencies[UNIT_REQUISITE_OVERRIDABLE], i)
cebe0d41 1588 if ((r = transaction_add_job_and_dependencies(m, JOB_VERIFY_ACTIVE, dep, ret, !override, override, false, false, ignore_order, e, NULL)) < 0) {
65e92d67 1589 log_warning("Cannot add dependency job for unit %s, ignoring: %s", dep->meta.id, bus_error(e, r));
60dc72b5
LP
1590
1591 if (e)
1592 dbus_error_free(e);
65e92d67 1593 }
9e2f7c11 1594
87f0e418 1595 SET_FOREACH(dep, ret->unit->meta.dependencies[UNIT_CONFLICTS], i)
cebe0d41 1596 if ((r = transaction_add_job_and_dependencies(m, JOB_STOP, dep, ret, true, override, true, false, ignore_order, e, NULL)) < 0) {
41242c42
LP
1597
1598 if (r != -EBADR)
1599 goto fail;
1600
1601 if (e)
1602 dbus_error_free(e);
1603 }
69dd2852
LP
1604
1605 SET_FOREACH(dep, ret->unit->meta.dependencies[UNIT_CONFLICTED_BY], i)
cebe0d41 1606 if ((r = transaction_add_job_and_dependencies(m, JOB_STOP, dep, ret, false, override, false, false, ignore_order, e, NULL)) < 0) {
41242c42
LP
1607 log_warning("Cannot add dependency job for unit %s, ignoring: %s", dep->meta.id, bus_error(e, r));
1608
1609 if (e)
1610 dbus_error_free(e);
1611 }
e5b5ae50 1612
4dcc1cb4
LP
1613 }
1614
1615 if (type == JOB_STOP || type == JOB_RESTART || type == JOB_TRY_RESTART) {
e5b5ae50 1616
87f0e418 1617 SET_FOREACH(dep, ret->unit->meta.dependencies[UNIT_REQUIRED_BY], i)
cebe0d41 1618 if ((r = transaction_add_job_and_dependencies(m, type, dep, ret, true, override, false, false, ignore_order, e, NULL)) < 0) {
41242c42
LP
1619
1620 if (r != -EBADR)
1621 goto fail;
1622
1623 if (e)
1624 dbus_error_free(e);
1625 }
b81884e7
LP
1626
1627 SET_FOREACH(dep, ret->unit->meta.dependencies[UNIT_BOUND_BY], i)
cebe0d41 1628 if ((r = transaction_add_job_and_dependencies(m, type, dep, ret, true, override, false, false, ignore_order, e, NULL)) < 0) {
41242c42
LP
1629
1630 if (r != -EBADR)
1631 goto fail;
1632
1633 if (e)
1634 dbus_error_free(e);
1635 }
e5b5ae50
LP
1636 }
1637
4dcc1cb4
LP
1638 if (type == JOB_RELOAD || type == JOB_RELOAD_OR_START) {
1639
1640 SET_FOREACH(dep, ret->unit->meta.dependencies[UNIT_PROPAGATE_RELOAD_TO], i) {
1641 r = transaction_add_job_and_dependencies(m, JOB_RELOAD, dep, ret, false, override, false, false, ignore_order, e, NULL);
1642
1643 if (r < 0) {
1644 log_warning("Cannot add dependency reload job for unit %s, ignoring: %s", dep->meta.id, bus_error(e, r));
1645
1646 if (e)
1647 dbus_error_free(e);
1648 }
1649 }
1650 }
1651
e5b5ae50
LP
1652 /* JOB_VERIFY_STARTED, JOB_RELOAD require no dependency handling */
1653 }
60918275 1654
c0dafa48
LP
1655 if (_ret)
1656 *_ret = ret;
1657
60918275
LP
1658 return 0;
1659
1660fail:
e5b5ae50
LP
1661 return r;
1662}
1663
c497c7a9
LP
1664static int transaction_add_isolate_jobs(Manager *m) {
1665 Iterator i;
1666 Unit *u;
1667 char *k;
1668 int r;
1669
1670 assert(m);
1671
1672 HASHMAP_FOREACH_KEY(u, k, m->units, i) {
1673
1674 /* ignore aliases */
1675 if (u->meta.id != k)
1676 continue;
1677
c8f4d764 1678 if (u->meta.ignore_on_isolate)
c497c7a9
LP
1679 continue;
1680
1681 /* No need to stop inactive jobs */
2ce5c8f9 1682 if (UNIT_IS_INACTIVE_OR_FAILED(unit_active_state(u)) && !u->meta.job)
c497c7a9
LP
1683 continue;
1684
1685 /* Is there already something listed for this? */
1686 if (hashmap_get(m->transaction_jobs, u))
1687 continue;
1688
cebe0d41 1689 if ((r = transaction_add_job_and_dependencies(m, JOB_STOP, u, NULL, true, false, false, false, false, NULL, NULL)) < 0)
c497c7a9
LP
1690 log_warning("Cannot add isolate job for unit %s, ignoring: %s", u->meta.id, strerror(-r));
1691 }
1692
1693 return 0;
1694}
1695
398ef8ba 1696int manager_add_job(Manager *m, JobType type, Unit *unit, JobMode mode, bool override, DBusError *e, Job **_ret) {
e5b5ae50
LP
1697 int r;
1698 Job *ret;
1699
1700 assert(m);
1701 assert(type < _JOB_TYPE_MAX);
87f0e418 1702 assert(unit);
e5b5ae50 1703 assert(mode < _JOB_MODE_MAX);
60918275 1704
398ef8ba
LP
1705 if (mode == JOB_ISOLATE && type != JOB_START) {
1706 dbus_set_error(e, BUS_ERROR_INVALID_JOB_MODE, "Isolate is only valid for start.");
c497c7a9 1707 return -EINVAL;
398ef8ba 1708 }
c497c7a9 1709
2528a7a6
LP
1710 if (mode == JOB_ISOLATE && !unit->meta.allow_isolate) {
1711 dbus_set_error(e, BUS_ERROR_NO_ISOLATION, "Operation refused, unit may not be isolated.");
1712 return -EPERM;
1713 }
1714
e43ac878 1715 log_debug("Trying to enqueue job %s/%s/%s", unit->meta.id, job_type_to_string(type), job_mode_to_string(mode));
9f04bd52 1716
cebe0d41
LP
1717 if ((r = transaction_add_job_and_dependencies(m, type, unit, NULL, true, override, false,
1718 mode == JOB_IGNORE_DEPENDENCIES || mode == JOB_IGNORE_REQUIREMENTS,
1719 mode == JOB_IGNORE_DEPENDENCIES, e, &ret)) < 0) {
11dd41ce 1720 transaction_abort(m);
e5b5ae50
LP
1721 return r;
1722 }
11dd41ce 1723
c497c7a9
LP
1724 if (mode == JOB_ISOLATE)
1725 if ((r = transaction_add_isolate_jobs(m)) < 0) {
1726 transaction_abort(m);
1727 return r;
1728 }
1729
398ef8ba 1730 if ((r = transaction_activate(m, mode, e)) < 0)
e5b5ae50
LP
1731 return r;
1732
9e2f7c11 1733 log_debug("Enqueued job %s/%s as %u", unit->meta.id, job_type_to_string(type), (unsigned) ret->id);
f50e0a01 1734
e5b5ae50
LP
1735 if (_ret)
1736 *_ret = ret;
60918275 1737
e5b5ae50
LP
1738 return 0;
1739}
60918275 1740
398ef8ba 1741int manager_add_job_by_name(Manager *m, JobType type, const char *name, JobMode mode, bool override, DBusError *e, Job **_ret) {
28247076
LP
1742 Unit *unit;
1743 int r;
1744
1745 assert(m);
1746 assert(type < _JOB_TYPE_MAX);
1747 assert(name);
1748 assert(mode < _JOB_MODE_MAX);
1749
398ef8ba 1750 if ((r = manager_load_unit(m, name, NULL, NULL, &unit)) < 0)
28247076
LP
1751 return r;
1752
398ef8ba 1753 return manager_add_job(m, type, unit, mode, override, e, _ret);
28247076
LP
1754}
1755
60918275
LP
1756Job *manager_get_job(Manager *m, uint32_t id) {
1757 assert(m);
1758
1759 return hashmap_get(m->jobs, UINT32_TO_PTR(id));
1760}
1761
87f0e418 1762Unit *manager_get_unit(Manager *m, const char *name) {
60918275
LP
1763 assert(m);
1764 assert(name);
1765
87f0e418 1766 return hashmap_get(m->units, name);
60918275
LP
1767}
1768
c1e1601e 1769unsigned manager_dispatch_load_queue(Manager *m) {
60918275 1770 Meta *meta;
c1e1601e 1771 unsigned n = 0;
60918275
LP
1772
1773 assert(m);
1774
223dabab
LP
1775 /* Make sure we are not run recursively */
1776 if (m->dispatching_load_queue)
c1e1601e 1777 return 0;
223dabab
LP
1778
1779 m->dispatching_load_queue = true;
1780
87f0e418 1781 /* Dispatches the load queue. Takes a unit from the queue and
60918275
LP
1782 * tries to load its data until the queue is empty */
1783
1784 while ((meta = m->load_queue)) {
034c6ed7
LP
1785 assert(meta->in_load_queue);
1786
399ab2b1 1787 unit_load((Unit*) meta);
c1e1601e 1788 n++;
60918275
LP
1789 }
1790
223dabab 1791 m->dispatching_load_queue = false;
c1e1601e 1792 return n;
60918275
LP
1793}
1794
398ef8ba 1795int manager_load_unit_prepare(Manager *m, const char *name, const char *path, DBusError *e, Unit **_ret) {
87f0e418 1796 Unit *ret;
60918275
LP
1797 int r;
1798
1799 assert(m);
9e2f7c11 1800 assert(name || path);
60918275 1801
db06e3b6
LP
1802 /* This will prepare the unit for loading, but not actually
1803 * load anything from disk. */
0301abf4 1804
398ef8ba
LP
1805 if (path && !is_path(path)) {
1806 dbus_set_error(e, BUS_ERROR_INVALID_PATH, "Path %s is not absolute.", path);
9e2f7c11 1807 return -EINVAL;
398ef8ba 1808 }
9e2f7c11
LP
1809
1810 if (!name)
1811 name = file_name_from_path(path);
1812
b9c0d441 1813 if (!unit_name_is_valid(name, false)) {
398ef8ba 1814 dbus_set_error(e, BUS_ERROR_INVALID_NAME, "Unit name %s is not valid.", name);
9e2f7c11 1815 return -EINVAL;
398ef8ba 1816 }
60918275 1817
87f0e418 1818 if ((ret = manager_get_unit(m, name))) {
034c6ed7 1819 *_ret = ret;
413d6313 1820 return 1;
034c6ed7 1821 }
60918275 1822
87f0e418 1823 if (!(ret = unit_new(m)))
60918275
LP
1824 return -ENOMEM;
1825
9e2f7c11 1826 if (path)
6be1e7d5 1827 if (!(ret->meta.fragment_path = strdup(path))) {
0301abf4
LP
1828 unit_free(ret);
1829 return -ENOMEM;
1830 }
0301abf4 1831
87f0e418
LP
1832 if ((r = unit_add_name(ret, name)) < 0) {
1833 unit_free(ret);
1ffba6fe 1834 return r;
60918275
LP
1835 }
1836
87f0e418 1837 unit_add_to_load_queue(ret);
c1e1601e 1838 unit_add_to_dbus_queue(ret);
949061f0 1839 unit_add_to_gc_queue(ret);
c1e1601e 1840
db06e3b6
LP
1841 if (_ret)
1842 *_ret = ret;
1843
1844 return 0;
1845}
1846
398ef8ba 1847int manager_load_unit(Manager *m, const char *name, const char *path, DBusError *e, Unit **_ret) {
db06e3b6
LP
1848 int r;
1849
1850 assert(m);
1851
1852 /* This will load the service information files, but not actually
1853 * start any services or anything. */
1854
398ef8ba 1855 if ((r = manager_load_unit_prepare(m, name, path, e, _ret)) != 0)
db06e3b6
LP
1856 return r;
1857
f50e0a01 1858 manager_dispatch_load_queue(m);
60918275 1859
9e2f7c11 1860 if (_ret)
413d6313 1861 *_ret = unit_follow_merge(*_ret);
9e2f7c11 1862
60918275
LP
1863 return 0;
1864}
a66d02c3 1865
cea8e32e 1866void manager_dump_jobs(Manager *s, FILE *f, const char *prefix) {
034c6ed7 1867 Iterator i;
a66d02c3
LP
1868 Job *j;
1869
1870 assert(s);
1871 assert(f);
1872
034c6ed7 1873 HASHMAP_FOREACH(j, s->jobs, i)
cea8e32e 1874 job_dump(j, f, prefix);
a66d02c3
LP
1875}
1876
87f0e418 1877void manager_dump_units(Manager *s, FILE *f, const char *prefix) {
034c6ed7 1878 Iterator i;
87f0e418 1879 Unit *u;
11dd41ce 1880 const char *t;
a66d02c3
LP
1881
1882 assert(s);
1883 assert(f);
1884
87f0e418 1885 HASHMAP_FOREACH_KEY(u, t, s->units, i)
9e2f7c11 1886 if (u->meta.id == t)
87f0e418 1887 unit_dump(u, f, prefix);
a66d02c3 1888}
7fad411c
LP
1889
1890void manager_clear_jobs(Manager *m) {
1891 Job *j;
1892
1893 assert(m);
1894
1895 transaction_abort(m);
1896
1897 while ((j = hashmap_first(m->jobs)))
c77bc38d 1898 job_finish_and_invalidate(j, JOB_CANCELED);
7fad411c 1899}
83c60c9f 1900
c1e1601e 1901unsigned manager_dispatch_run_queue(Manager *m) {
83c60c9f 1902 Job *j;
c1e1601e 1903 unsigned n = 0;
83c60c9f 1904
034c6ed7 1905 if (m->dispatching_run_queue)
c1e1601e 1906 return 0;
034c6ed7
LP
1907
1908 m->dispatching_run_queue = true;
9152c765 1909
034c6ed7 1910 while ((j = m->run_queue)) {
ac1135be 1911 assert(j->installed);
034c6ed7
LP
1912 assert(j->in_run_queue);
1913
1914 job_run_and_invalidate(j);
c1e1601e 1915 n++;
9152c765 1916 }
034c6ed7
LP
1917
1918 m->dispatching_run_queue = false;
c1e1601e
LP
1919 return n;
1920}
1921
1922unsigned manager_dispatch_dbus_queue(Manager *m) {
1923 Job *j;
1924 Meta *meta;
1925 unsigned n = 0;
1926
1927 assert(m);
1928
1929 if (m->dispatching_dbus_queue)
1930 return 0;
1931
1932 m->dispatching_dbus_queue = true;
1933
1934 while ((meta = m->dbus_unit_queue)) {
23a177ef 1935 assert(meta->in_dbus_queue);
c1e1601e 1936
399ab2b1 1937 bus_unit_send_change_signal((Unit*) meta);
c1e1601e
LP
1938 n++;
1939 }
1940
1941 while ((j = m->dbus_job_queue)) {
1942 assert(j->in_dbus_queue);
1943
1944 bus_job_send_change_signal(j);
1945 n++;
1946 }
1947
1948 m->dispatching_dbus_queue = false;
1949 return n;
9152c765
LP
1950}
1951
8c47c732
LP
1952static int manager_process_notify_fd(Manager *m) {
1953 ssize_t n;
1954
1955 assert(m);
1956
1957 for (;;) {
1958 char buf[4096];
1959 struct msghdr msghdr;
1960 struct iovec iovec;
1961 struct ucred *ucred;
1962 union {
1963 struct cmsghdr cmsghdr;
1964 uint8_t buf[CMSG_SPACE(sizeof(struct ucred))];
1965 } control;
1966 Unit *u;
1967 char **tags;
1968
1969 zero(iovec);
1970 iovec.iov_base = buf;
1971 iovec.iov_len = sizeof(buf)-1;
1972
1973 zero(control);
1974 zero(msghdr);
1975 msghdr.msg_iov = &iovec;
1976 msghdr.msg_iovlen = 1;
1977 msghdr.msg_control = &control;
1978 msghdr.msg_controllen = sizeof(control);
1979
1980 if ((n = recvmsg(m->notify_watch.fd, &msghdr, MSG_DONTWAIT)) <= 0) {
1981 if (n >= 0)
1982 return -EIO;
1983
f6144808 1984 if (errno == EAGAIN || errno == EINTR)
8c47c732
LP
1985 break;
1986
1987 return -errno;
1988 }
1989
1990 if (msghdr.msg_controllen < CMSG_LEN(sizeof(struct ucred)) ||
1991 control.cmsghdr.cmsg_level != SOL_SOCKET ||
1992 control.cmsghdr.cmsg_type != SCM_CREDENTIALS ||
1993 control.cmsghdr.cmsg_len != CMSG_LEN(sizeof(struct ucred))) {
1994 log_warning("Received notify message without credentials. Ignoring.");
1995 continue;
1996 }
1997
1998 ucred = (struct ucred*) CMSG_DATA(&control.cmsghdr);
1999
c6c18be3 2000 if (!(u = hashmap_get(m->watch_pids, LONG_TO_PTR(ucred->pid))))
8c47c732
LP
2001 if (!(u = cgroup_unit_by_pid(m, ucred->pid))) {
2002 log_warning("Cannot find unit for notify message of PID %lu.", (unsigned long) ucred->pid);
2003 continue;
2004 }
2005
8c40acf7
LP
2006 assert((size_t) n < sizeof(buf));
2007 buf[n] = 0;
8c47c732
LP
2008 if (!(tags = strv_split(buf, "\n\r")))
2009 return -ENOMEM;
2010
2011 log_debug("Got notification message for unit %s", u->meta.id);
2012
2013 if (UNIT_VTABLE(u)->notify_message)
c952c6ec 2014 UNIT_VTABLE(u)->notify_message(u, ucred->pid, tags);
8c47c732
LP
2015
2016 strv_free(tags);
2017 }
2018
2019 return 0;
2020}
2021
034c6ed7 2022static int manager_dispatch_sigchld(Manager *m) {
9152c765
LP
2023 assert(m);
2024
2025 for (;;) {
2026 siginfo_t si;
87f0e418 2027 Unit *u;
8c47c732 2028 int r;
9152c765
LP
2029
2030 zero(si);
4112df16
LP
2031
2032 /* First we call waitd() for a PID and do not reap the
2033 * zombie. That way we can still access /proc/$PID for
2034 * it while it is a zombie. */
2035 if (waitid(P_ALL, 0, &si, WEXITED|WNOHANG|WNOWAIT) < 0) {
acbb0225
LP
2036
2037 if (errno == ECHILD)
2038 break;
2039
4112df16
LP
2040 if (errno == EINTR)
2041 continue;
2042
9152c765 2043 return -errno;
acbb0225 2044 }
9152c765 2045
4112df16 2046 if (si.si_pid <= 0)
9152c765
LP
2047 break;
2048
15d5d9d9 2049 if (si.si_code == CLD_EXITED || si.si_code == CLD_KILLED || si.si_code == CLD_DUMPED) {
4112df16
LP
2050 char *name = NULL;
2051
87d2c1ff 2052 get_process_comm(si.si_pid, &name);
bb00e604 2053 log_debug("Got SIGCHLD for process %lu (%s)", (unsigned long) si.si_pid, strna(name));
4112df16
LP
2054 free(name);
2055 }
2056
8c47c732
LP
2057 /* Let's flush any message the dying child might still
2058 * have queued for us. This ensures that the process
2059 * still exists in /proc so that we can figure out
2060 * which cgroup and hence unit it belongs to. */
2061 if ((r = manager_process_notify_fd(m)) < 0)
2062 return r;
2063
2064 /* And now figure out the unit this belongs to */
c6c18be3 2065 if (!(u = hashmap_get(m->watch_pids, LONG_TO_PTR(si.si_pid))))
8c47c732
LP
2066 u = cgroup_unit_by_pid(m, si.si_pid);
2067
4112df16
LP
2068 /* And now, we actually reap the zombie. */
2069 if (waitid(P_PID, si.si_pid, &si, WEXITED) < 0) {
2070 if (errno == EINTR)
2071 continue;
2072
2073 return -errno;
2074 }
2075
034c6ed7
LP
2076 if (si.si_code != CLD_EXITED && si.si_code != CLD_KILLED && si.si_code != CLD_DUMPED)
2077 continue;
2078
bb00e604
LP
2079 log_debug("Child %lu died (code=%s, status=%i/%s)",
2080 (long unsigned) si.si_pid,
4112df16
LP
2081 sigchld_code_to_string(si.si_code),
2082 si.si_status,
d06dacd0
LP
2083 strna(si.si_code == CLD_EXITED
2084 ? exit_status_to_string(si.si_status, EXIT_STATUS_FULL)
2085 : signal_to_string(si.si_status)));
acbb0225 2086
8c47c732 2087 if (!u)
9152c765
LP
2088 continue;
2089
c6c18be3 2090 log_debug("Child %lu belongs to %s", (long unsigned) si.si_pid, u->meta.id);
6c1a0478 2091
c6c18be3 2092 hashmap_remove(m->watch_pids, LONG_TO_PTR(si.si_pid));
87f0e418 2093 UNIT_VTABLE(u)->sigchld_event(u, si.si_pid, si.si_code, si.si_status);
9152c765
LP
2094 }
2095
2096 return 0;
2097}
2098
7d793605 2099static int manager_start_target(Manager *m, const char *name, JobMode mode) {
28247076 2100 int r;
398ef8ba
LP
2101 DBusError error;
2102
2103 dbus_error_init(&error);
2104
af2d49f7 2105 log_debug("Activating special unit %s", name);
1e001f52 2106
398ef8ba
LP
2107 if ((r = manager_add_job_by_name(m, JOB_START, name, mode, true, &error, NULL)) < 0)
2108 log_error("Failed to enqueue %s job: %s", name, bus_error(&error, r));
28247076 2109
398ef8ba 2110 dbus_error_free(&error);
a1b256b0
LP
2111
2112 return r;
28247076
LP
2113}
2114
a16e1123 2115static int manager_process_signal_fd(Manager *m) {
9152c765
LP
2116 ssize_t n;
2117 struct signalfd_siginfo sfsi;
2118 bool sigchld = false;
2119
2120 assert(m);
2121
2122 for (;;) {
acbb0225 2123 if ((n = read(m->signal_watch.fd, &sfsi, sizeof(sfsi))) != sizeof(sfsi)) {
9152c765
LP
2124
2125 if (n >= 0)
2126 return -EIO;
2127
63090775 2128 if (errno == EINTR || errno == EAGAIN)
acbb0225 2129 break;
9152c765
LP
2130
2131 return -errno;
2132 }
2133
67370238
LP
2134 if (sfsi.ssi_pid > 0) {
2135 char *p = NULL;
2136
87d2c1ff 2137 get_process_comm(sfsi.ssi_pid, &p);
dfa7f7e1 2138
67370238 2139 log_debug("Received SIG%s from PID %lu (%s).",
4e240ab0 2140 signal_to_string(sfsi.ssi_signo),
67370238
LP
2141 (unsigned long) sfsi.ssi_pid, strna(p));
2142 free(p);
2143 } else
4e240ab0 2144 log_debug("Received SIG%s.", signal_to_string(sfsi.ssi_signo));
1e001f52 2145
b9cd2ec1
LP
2146 switch (sfsi.ssi_signo) {
2147
4112df16 2148 case SIGCHLD:
9152c765 2149 sigchld = true;
b9cd2ec1
LP
2150 break;
2151
6632c602 2152 case SIGTERM:
a3d4e06d 2153 if (m->running_as == MANAGER_SYSTEM) {
db06e3b6
LP
2154 /* This is for compatibility with the
2155 * original sysvinit */
e11dc4a2 2156 m->exit_code = MANAGER_REEXECUTE;
a1b256b0
LP
2157 break;
2158 }
84e9af1e 2159
a1b256b0 2160 /* Fall through */
e11dc4a2
LP
2161
2162 case SIGINT:
a3d4e06d 2163 if (m->running_as == MANAGER_SYSTEM) {
7d793605 2164 manager_start_target(m, SPECIAL_CTRL_ALT_DEL_TARGET, JOB_REPLACE);
84e9af1e
LP
2165 break;
2166 }
2167
a1b256b0 2168 /* Run the exit target if there is one, if not, just exit. */
0003d1ab 2169 if (manager_start_target(m, SPECIAL_EXIT_TARGET, JOB_REPLACE) < 0) {
a1b256b0
LP
2170 m->exit_code = MANAGER_EXIT;
2171 return 0;
2172 }
2173
2174 break;
84e9af1e 2175
28247076 2176 case SIGWINCH:
a3d4e06d 2177 if (m->running_as == MANAGER_SYSTEM)
7d793605 2178 manager_start_target(m, SPECIAL_KBREQUEST_TARGET, JOB_REPLACE);
84e9af1e 2179
28247076
LP
2180 /* This is a nop on non-init */
2181 break;
84e9af1e 2182
28247076 2183 case SIGPWR:
a3d4e06d 2184 if (m->running_as == MANAGER_SYSTEM)
7d793605 2185 manager_start_target(m, SPECIAL_SIGPWR_TARGET, JOB_REPLACE);
84e9af1e 2186
28247076 2187 /* This is a nop on non-init */
84e9af1e 2188 break;
6632c602 2189
1005d14f 2190 case SIGUSR1: {
57ee42ce
LP
2191 Unit *u;
2192
2193 u = manager_get_unit(m, SPECIAL_DBUS_SERVICE);
2194
2195 if (!u || UNIT_IS_ACTIVE_OR_RELOADING(unit_active_state(u))) {
2196 log_info("Trying to reconnect to bus...");
3996fbe2 2197 bus_init(m, true);
57ee42ce
LP
2198 }
2199
2200 if (!u || !UNIT_IS_ACTIVE_OR_ACTIVATING(unit_active_state(u))) {
2201 log_info("Loading D-Bus service...");
7d793605 2202 manager_start_target(m, SPECIAL_DBUS_SERVICE, JOB_REPLACE);
57ee42ce
LP
2203 }
2204
2205 break;
2206 }
2207
2149e37c
LP
2208 case SIGUSR2: {
2209 FILE *f;
2210 char *dump = NULL;
2211 size_t size;
2212
2213 if (!(f = open_memstream(&dump, &size))) {
2214 log_warning("Failed to allocate memory stream.");
2215 break;
2216 }
2217
2218 manager_dump_units(m, f, "\t");
2219 manager_dump_jobs(m, f, "\t");
2220
2221 if (ferror(f)) {
2222 fclose(f);
2223 free(dump);
2224 log_warning("Failed to write status stream");
2225 break;
2226 }
2227
2228 fclose(f);
2229 log_dump(LOG_INFO, dump);
2230 free(dump);
2231
1005d14f 2232 break;
2149e37c 2233 }
1005d14f 2234
a16e1123
LP
2235 case SIGHUP:
2236 m->exit_code = MANAGER_RELOAD;
2237 break;
2238
7d793605 2239 default: {
253ee27a 2240
0003d1ab
LP
2241 /* Starting SIGRTMIN+0 */
2242 static const char * const target_table[] = {
7d793605
LP
2243 [0] = SPECIAL_DEFAULT_TARGET,
2244 [1] = SPECIAL_RESCUE_TARGET,
f057408c 2245 [2] = SPECIAL_EMERGENCY_TARGET,
7d793605
LP
2246 [3] = SPECIAL_HALT_TARGET,
2247 [4] = SPECIAL_POWEROFF_TARGET,
0003d1ab
LP
2248 [5] = SPECIAL_REBOOT_TARGET,
2249 [6] = SPECIAL_KEXEC_TARGET
2250 };
2251
2252 /* Starting SIGRTMIN+13, so that target halt and system halt are 10 apart */
2253 static const ManagerExitCode code_table[] = {
2254 [0] = MANAGER_HALT,
2255 [1] = MANAGER_POWEROFF,
2256 [2] = MANAGER_REBOOT,
2257 [3] = MANAGER_KEXEC
7d793605
LP
2258 };
2259
2260 if ((int) sfsi.ssi_signo >= SIGRTMIN+0 &&
0003d1ab 2261 (int) sfsi.ssi_signo < SIGRTMIN+(int) ELEMENTSOF(target_table)) {
764e9b5f
MS
2262 int idx = (int) sfsi.ssi_signo - SIGRTMIN;
2263 manager_start_target(m, target_table[idx],
2264 (idx == 1 || idx == 2) ? JOB_ISOLATE : JOB_REPLACE);
7d793605
LP
2265 break;
2266 }
2267
0003d1ab
LP
2268 if ((int) sfsi.ssi_signo >= SIGRTMIN+13 &&
2269 (int) sfsi.ssi_signo < SIGRTMIN+13+(int) ELEMENTSOF(code_table)) {
2270 m->exit_code = code_table[sfsi.ssi_signo - SIGRTMIN - 13];
2271 break;
2272 }
2273
0658666b
LP
2274 switch (sfsi.ssi_signo - SIGRTMIN) {
2275
2276 case 20:
2277 log_debug("Enabling showing of status.");
27d340c7 2278 manager_set_show_status(m, true);
0658666b
LP
2279 break;
2280
2281 case 21:
2282 log_debug("Disabling showing of status.");
27d340c7 2283 manager_set_show_status(m, false);
0658666b
LP
2284 break;
2285
253ee27a
LP
2286 case 22:
2287 log_set_max_level(LOG_DEBUG);
2288 log_notice("Setting log level to debug.");
2289 break;
2290
2291 case 23:
2292 log_set_max_level(LOG_INFO);
2293 log_notice("Setting log level to info.");
2294 break;
2295
2296 case 27:
2297 log_set_target(LOG_TARGET_CONSOLE);
2298 log_notice("Setting log target to console.");
2299 break;
2300
2301 case 28:
2302 log_set_target(LOG_TARGET_KMSG);
2303 log_notice("Setting log target to kmsg.");
2304 break;
2305
2306 case 29:
2307 log_set_target(LOG_TARGET_SYSLOG_OR_KMSG);
2308 log_notice("Setting log target to syslog-or-kmsg.");
2309 break;
2310
0658666b 2311 default:
4e240ab0 2312 log_warning("Got unhandled signal <%s>.", signal_to_string(sfsi.ssi_signo));
0658666b 2313 }
b9cd2ec1 2314 }
7d793605 2315 }
9152c765
LP
2316 }
2317
2318 if (sigchld)
034c6ed7
LP
2319 return manager_dispatch_sigchld(m);
2320
2321 return 0;
2322}
2323
a16e1123 2324static int process_event(Manager *m, struct epoll_event *ev) {
034c6ed7 2325 int r;
acbb0225 2326 Watch *w;
034c6ed7
LP
2327
2328 assert(m);
2329 assert(ev);
2330
3df5bf61 2331 assert_se(w = ev->data.ptr);
034c6ed7 2332
40dde66f
LP
2333 if (w->type == WATCH_INVALID)
2334 return 0;
2335
acbb0225 2336 switch (w->type) {
034c6ed7 2337
ef734fd6 2338 case WATCH_SIGNAL:
034c6ed7 2339
acbb0225 2340 /* An incoming signal? */
f94ea366 2341 if (ev->events != EPOLLIN)
acbb0225 2342 return -EINVAL;
034c6ed7 2343
a16e1123 2344 if ((r = manager_process_signal_fd(m)) < 0)
acbb0225 2345 return r;
034c6ed7 2346
acbb0225 2347 break;
034c6ed7 2348
8c47c732
LP
2349 case WATCH_NOTIFY:
2350
2351 /* An incoming daemon notification event? */
2352 if (ev->events != EPOLLIN)
2353 return -EINVAL;
2354
2355 if ((r = manager_process_notify_fd(m)) < 0)
2356 return r;
2357
2358 break;
2359
acbb0225 2360 case WATCH_FD:
034c6ed7 2361
acbb0225 2362 /* Some fd event, to be dispatched to the units */
ea430986 2363 UNIT_VTABLE(w->data.unit)->fd_event(w->data.unit, w->fd, ev->events, w);
acbb0225 2364 break;
034c6ed7 2365
faf919f1
LP
2366 case WATCH_UNIT_TIMER:
2367 case WATCH_JOB_TIMER: {
acbb0225
LP
2368 uint64_t v;
2369 ssize_t k;
034c6ed7 2370
acbb0225 2371 /* Some timer event, to be dispatched to the units */
be888ebb 2372 if ((k = read(w->fd, &v, sizeof(v))) != sizeof(v)) {
034c6ed7 2373
acbb0225
LP
2374 if (k < 0 && (errno == EINTR || errno == EAGAIN))
2375 break;
034c6ed7 2376
acbb0225 2377 return k < 0 ? -errno : -EIO;
034c6ed7
LP
2378 }
2379
faf919f1
LP
2380 if (w->type == WATCH_UNIT_TIMER)
2381 UNIT_VTABLE(w->data.unit)->timer_event(w->data.unit, v, w);
2382 else
2383 job_timer_event(w->data.job, v, w);
acbb0225
LP
2384 break;
2385 }
2386
ef734fd6
LP
2387 case WATCH_MOUNT:
2388 /* Some mount table change, intended for the mount subsystem */
2389 mount_fd_event(m, ev->events);
2390 break;
2391
4e434314
LP
2392 case WATCH_SWAP:
2393 /* Some swap table change, intended for the swap subsystem */
2394 swap_fd_event(m, ev->events);
2395 break;
2396
f94ea366
LP
2397 case WATCH_UDEV:
2398 /* Some notification from udev, intended for the device subsystem */
2399 device_fd_event(m, ev->events);
2400 break;
2401
ea430986
LP
2402 case WATCH_DBUS_WATCH:
2403 bus_watch_event(m, w, ev->events);
2404 break;
2405
2406 case WATCH_DBUS_TIMEOUT:
2407 bus_timeout_event(m, w, ev->events);
2408 break;
2409
acbb0225 2410 default:
c5fd1e57 2411 log_error("event type=%i", w->type);
acbb0225 2412 assert_not_reached("Unknown epoll event type.");
034c6ed7 2413 }
9152c765
LP
2414
2415 return 0;
2416}
2417
2418int manager_loop(Manager *m) {
2419 int r;
9152c765 2420
fac9f8df 2421 RATELIMIT_DEFINE(rl, 1*USEC_PER_SEC, 50000);
ea430986 2422
9152c765 2423 assert(m);
a16e1123 2424 m->exit_code = MANAGER_RUNNING;
9152c765 2425
fe51822e
LP
2426 /* Release the path cache */
2427 set_free_free(m->unit_path_cache);
2428 m->unit_path_cache = NULL;
2429
b0c918b9
LP
2430 manager_check_finished(m);
2431
a4312405
LP
2432 /* There might still be some zombies hanging around from
2433 * before we were exec()'ed. Leat's reap them */
2434 if ((r = manager_dispatch_sigchld(m)) < 0)
2435 return r;
2436
a16e1123 2437 while (m->exit_code == MANAGER_RUNNING) {
957ca890
LP
2438 struct epoll_event event;
2439 int n;
9152c765 2440
ea430986
LP
2441 if (!ratelimit_test(&rl)) {
2442 /* Yay, something is going seriously wrong, pause a little */
2443 log_warning("Looping too fast. Throttling execution a little.");
2444 sleep(1);
2445 }
2446
37a8e683 2447 if (manager_dispatch_load_queue(m) > 0)
23a177ef
LP
2448 continue;
2449
37a8e683 2450 if (manager_dispatch_run_queue(m) > 0)
701cc384
LP
2451 continue;
2452
37a8e683 2453 if (bus_dispatch(m) > 0)
c1e1601e 2454 continue;
034c6ed7 2455
37a8e683 2456 if (manager_dispatch_cleanup_queue(m) > 0)
c1e1601e
LP
2457 continue;
2458
37a8e683 2459 if (manager_dispatch_gc_queue(m) > 0)
c1e1601e
LP
2460 continue;
2461
2462 if (manager_dispatch_dbus_queue(m) > 0)
ea430986 2463 continue;
ea430986 2464
e04aad61
LP
2465 if (swap_dispatch_reload(m) > 0)
2466 continue;
2467
957ca890 2468 if ((n = epoll_wait(m->epoll_fd, &event, 1, -1)) < 0) {
9152c765 2469
6089f4a9 2470 if (errno == EINTR)
9152c765
LP
2471 continue;
2472
2473 return -errno;
2474 }
2475
957ca890 2476 assert(n == 1);
b9cd2ec1 2477
a16e1123 2478 if ((r = process_event(m, &event)) < 0)
957ca890 2479 return r;
a16e1123 2480 }
957ca890 2481
a16e1123 2482 return m->exit_code;
83c60c9f 2483}
ea430986
LP
2484
2485int manager_get_unit_from_dbus_path(Manager *m, const char *s, Unit **_u) {
2486 char *n;
2487 Unit *u;
2488
2489 assert(m);
2490 assert(s);
2491 assert(_u);
2492
2493 if (!startswith(s, "/org/freedesktop/systemd1/unit/"))
2494 return -EINVAL;
2495
2496 if (!(n = bus_path_unescape(s+31)))
2497 return -ENOMEM;
2498
2499 u = manager_get_unit(m, n);
2500 free(n);
2501
2502 if (!u)
2503 return -ENOENT;
2504
2505 *_u = u;
2506
2507 return 0;
2508}
86fbf370
LP
2509
2510int manager_get_job_from_dbus_path(Manager *m, const char *s, Job **_j) {
2511 Job *j;
2512 unsigned id;
2513 int r;
2514
2515 assert(m);
2516 assert(s);
2517 assert(_j);
2518
2519 if (!startswith(s, "/org/freedesktop/systemd1/job/"))
2520 return -EINVAL;
2521
2522 if ((r = safe_atou(s + 30, &id)) < 0)
2523 return r;
2524
2525 if (!(j = manager_get_job(m, id)))
2526 return -ENOENT;
2527
2528 *_j = j;
2529
2530 return 0;
2531}
dfcd764e 2532
4927fcae 2533void manager_send_unit_audit(Manager *m, Unit *u, int type, bool success) {
e537352b 2534
4927fcae
LP
2535#ifdef HAVE_AUDIT
2536 char *p;
e537352b 2537
4927fcae 2538 if (m->audit_fd < 0)
e537352b
LP
2539 return;
2540
bbd3a7ba
LP
2541 /* Don't generate audit events if the service was already
2542 * started and we're just deserializing */
a7556052 2543 if (m->n_reloading > 0)
bbd3a7ba
LP
2544 return;
2545
f1dd0c3f
LP
2546 if (m->running_as != MANAGER_SYSTEM)
2547 return;
2548
2549 if (u->meta.type != UNIT_SERVICE)
2550 return;
2551
4927fcae
LP
2552 if (!(p = unit_name_to_prefix_and_instance(u->meta.id))) {
2553 log_error("Failed to allocate unit name for audit message: %s", strerror(ENOMEM));
e537352b
LP
2554 return;
2555 }
2556
391ade86
LP
2557 if (audit_log_user_comm_message(m->audit_fd, type, "", p, NULL, NULL, NULL, success) < 0) {
2558 log_warning("Failed to send audit message: %m");
2559
2560 if (errno == EPERM) {
2561 /* We aren't allowed to send audit messages?
2562 * Then let's not retry again, to avoid
2563 * spamming the user with the same and same
2564 * messages over and over. */
2565
2566 audit_close(m->audit_fd);
2567 m->audit_fd = -1;
2568 }
2569 }
e537352b 2570
4927fcae
LP
2571 free(p);
2572#endif
e537352b 2573
e537352b
LP
2574}
2575
e983b760
LP
2576void manager_send_unit_plymouth(Manager *m, Unit *u) {
2577 int fd = -1;
2578 union sockaddr_union sa;
2579 int n = 0;
2580 char *message = NULL;
e983b760
LP
2581
2582 /* Don't generate plymouth events if the service was already
2583 * started and we're just deserializing */
a7556052 2584 if (m->n_reloading > 0)
e983b760
LP
2585 return;
2586
2587 if (m->running_as != MANAGER_SYSTEM)
2588 return;
2589
2590 if (u->meta.type != UNIT_SERVICE &&
2591 u->meta.type != UNIT_MOUNT &&
2592 u->meta.type != UNIT_SWAP)
2593 return;
2594
2595 /* We set SOCK_NONBLOCK here so that we rather drop the
2596 * message then wait for plymouth */
2597 if ((fd = socket(AF_UNIX, SOCK_STREAM|SOCK_CLOEXEC|SOCK_NONBLOCK, 0)) < 0) {
2598 log_error("socket() failed: %m");
2599 return;
2600 }
2601
2602 zero(sa);
2603 sa.sa.sa_family = AF_UNIX;
96707269
LP
2604 strncpy(sa.un.sun_path+1, "/org/freedesktop/plymouthd", sizeof(sa.un.sun_path)-1);
2605 if (connect(fd, &sa.sa, offsetof(struct sockaddr_un, sun_path) + 1 + strlen(sa.un.sun_path+1)) < 0) {
e983b760
LP
2606
2607 if (errno != EPIPE &&
2608 errno != EAGAIN &&
2609 errno != ENOENT &&
2610 errno != ECONNREFUSED &&
2611 errno != ECONNRESET &&
2612 errno != ECONNABORTED)
2613 log_error("connect() failed: %m");
2614
2615 goto finish;
2616 }
2617
2618 if (asprintf(&message, "U\002%c%s%n", (int) (strlen(u->meta.id) + 1), u->meta.id, &n) < 0) {
2619 log_error("Out of memory");
2620 goto finish;
2621 }
2622
2623 errno = 0;
bd40a2d8 2624 if (write(fd, message, n + 1) != n + 1) {
e983b760
LP
2625
2626 if (errno != EPIPE &&
2627 errno != EAGAIN &&
2628 errno != ENOENT &&
2629 errno != ECONNREFUSED &&
2630 errno != ECONNRESET &&
2631 errno != ECONNABORTED)
2632 log_error("Failed to write Plymouth message: %m");
2633
2634 goto finish;
2635 }
2636
2637finish:
2638 if (fd >= 0)
2639 close_nointr_nofail(fd);
2640
2641 free(message);
2642}
2643
05e343b7
LP
2644void manager_dispatch_bus_name_owner_changed(
2645 Manager *m,
2646 const char *name,
2647 const char* old_owner,
2648 const char *new_owner) {
2649
2650 Unit *u;
2651
2652 assert(m);
2653 assert(name);
2654
2655 if (!(u = hashmap_get(m->watch_bus, name)))
2656 return;
2657
2658 UNIT_VTABLE(u)->bus_name_owner_change(u, name, old_owner, new_owner);
2659}
2660
2661void manager_dispatch_bus_query_pid_done(
2662 Manager *m,
2663 const char *name,
2664 pid_t pid) {
2665
2666 Unit *u;
2667
2668 assert(m);
2669 assert(name);
2670 assert(pid >= 1);
2671
2672 if (!(u = hashmap_get(m->watch_bus, name)))
2673 return;
2674
2675 UNIT_VTABLE(u)->bus_query_pid_done(u, name, pid);
2676}
2677
d8d5ab98 2678int manager_open_serialization(Manager *m, FILE **_f) {
b925e726 2679 char *path = NULL;
a16e1123
LP
2680 mode_t saved_umask;
2681 int fd;
2682 FILE *f;
2683
2684 assert(_f);
2685
b925e726 2686 if (m->running_as == MANAGER_SYSTEM)
2b583ce6 2687 asprintf(&path, "/run/systemd/dump-%lu-XXXXXX", (unsigned long) getpid());
b925e726
LP
2688 else
2689 asprintf(&path, "/tmp/systemd-dump-%lu-XXXXXX", (unsigned long) getpid());
d8d5ab98 2690
b925e726
LP
2691 if (!path)
2692 return -ENOMEM;
a16e1123
LP
2693
2694 saved_umask = umask(0077);
2695 fd = mkostemp(path, O_RDWR|O_CLOEXEC);
2696 umask(saved_umask);
2697
2698 if (fd < 0) {
2699 free(path);
2700 return -errno;
2701 }
2702
2703 unlink(path);
2704
2705 log_debug("Serializing state to %s", path);
2706 free(path);
2707
da19d5c1 2708 if (!(f = fdopen(fd, "w+")))
a16e1123
LP
2709 return -errno;
2710
2711 *_f = f;
2712
2713 return 0;
2714}
2715
2716int manager_serialize(Manager *m, FILE *f, FDSet *fds) {
2717 Iterator i;
2718 Unit *u;
2719 const char *t;
2720 int r;
2721
2722 assert(m);
2723 assert(f);
2724 assert(fds);
2725
a7556052 2726 m->n_reloading ++;
38c52d46 2727
01d67b43
LP
2728 fprintf(f, "current-job-id=%i\n", m->current_job_id);
2729 fprintf(f, "taint-usr=%s\n", yes_no(m->taint_usr));
2730
e9ddabc2 2731 dual_timestamp_serialize(f, "initrd-timestamp", &m->initrd_timestamp);
10717a1a
LP
2732 dual_timestamp_serialize(f, "startup-timestamp", &m->startup_timestamp);
2733 dual_timestamp_serialize(f, "finish-timestamp", &m->finish_timestamp);
47a483a1 2734
f2382a94
LP
2735 fputc('\n', f);
2736
a16e1123
LP
2737 HASHMAP_FOREACH_KEY(u, t, m->units, i) {
2738 if (u->meta.id != t)
2739 continue;
2740
2741 if (!unit_can_serialize(u))
2742 continue;
2743
2744 /* Start marker */
2745 fputs(u->meta.id, f);
2746 fputc('\n', f);
2747
38c52d46 2748 if ((r = unit_serialize(u, f, fds)) < 0) {
a7556052 2749 m->n_reloading --;
a16e1123 2750 return r;
38c52d46 2751 }
a16e1123
LP
2752 }
2753
a7556052
LP
2754 assert(m->n_reloading > 0);
2755 m->n_reloading --;
38c52d46 2756
a16e1123
LP
2757 if (ferror(f))
2758 return -EIO;
2759
b23de6af
LP
2760 r = bus_fdset_add_all(m, fds);
2761 if (r < 0)
2762 return r;
2763
a16e1123
LP
2764 return 0;
2765}
2766
2767int manager_deserialize(Manager *m, FILE *f, FDSet *fds) {
2768 int r = 0;
2769
2770 assert(m);
2771 assert(f);
2772
2773 log_debug("Deserializing state...");
2774
a7556052 2775 m->n_reloading ++;
82c64bf5 2776
10f8e83c 2777 for (;;) {
20c03b7b 2778 char line[LINE_MAX], *l;
10f8e83c
LP
2779
2780 if (!fgets(line, sizeof(line), f)) {
2781 if (feof(f))
2782 r = 0;
2783 else
2784 r = -errno;
2785
2786 goto finish;
2787 }
2788
2789 char_array_0(line);
2790 l = strstrip(line);
2791
2792 if (l[0] == 0)
2793 break;
2794
01d67b43
LP
2795 if (startswith(l, "current-job-id=")) {
2796 uint32_t id;
2797
2798 if (safe_atou32(l+15, &id) < 0)
2799 log_debug("Failed to parse current job id value %s", l+15);
2800 else
2801 m->current_job_id = MAX(m->current_job_id, id);
2802 } else if (startswith(l, "taint-usr=")) {
2803 int b;
2804
2805 if ((b = parse_boolean(l+10)) < 0)
2806 log_debug("Failed to parse taint /usr flag %s", l+10);
2807 else
2808 m->taint_usr = m->taint_usr || b;
2809 } else if (startswith(l, "initrd-timestamp="))
e9ddabc2
LP
2810 dual_timestamp_deserialize(l+17, &m->initrd_timestamp);
2811 else if (startswith(l, "startup-timestamp="))
799fd0fd 2812 dual_timestamp_deserialize(l+18, &m->startup_timestamp);
10717a1a 2813 else if (startswith(l, "finish-timestamp="))
799fd0fd 2814 dual_timestamp_deserialize(l+17, &m->finish_timestamp);
10717a1a 2815 else
10f8e83c
LP
2816 log_debug("Unknown serialization item '%s'", l);
2817 }
2818
a16e1123
LP
2819 for (;;) {
2820 Unit *u;
2821 char name[UNIT_NAME_MAX+2];
2822
2823 /* Start marker */
2824 if (!fgets(name, sizeof(name), f)) {
2825 if (feof(f))
10f8e83c
LP
2826 r = 0;
2827 else
2828 r = -errno;
a16e1123 2829
82c64bf5 2830 goto finish;
a16e1123
LP
2831 }
2832
2833 char_array_0(name);
2834
398ef8ba 2835 if ((r = manager_load_unit(m, strstrip(name), NULL, NULL, &u)) < 0)
82c64bf5 2836 goto finish;
a16e1123
LP
2837
2838 if ((r = unit_deserialize(u, f, fds)) < 0)
82c64bf5 2839 goto finish;
a16e1123
LP
2840 }
2841
10f8e83c 2842finish:
82c64bf5
LP
2843 if (ferror(f)) {
2844 r = -EIO;
2845 goto finish;
2846 }
a16e1123 2847
a7556052
LP
2848 assert(m->n_reloading > 0);
2849 m->n_reloading --;
82c64bf5
LP
2850
2851 return r;
a16e1123
LP
2852}
2853
2854int manager_reload(Manager *m) {
2855 int r, q;
2856 FILE *f;
2857 FDSet *fds;
2858
2859 assert(m);
2860
d8d5ab98 2861 if ((r = manager_open_serialization(m, &f)) < 0)
a16e1123
LP
2862 return r;
2863
a7556052 2864 m->n_reloading ++;
38c52d46 2865
a16e1123 2866 if (!(fds = fdset_new())) {
a7556052 2867 m->n_reloading --;
a16e1123
LP
2868 r = -ENOMEM;
2869 goto finish;
2870 }
2871
38c52d46 2872 if ((r = manager_serialize(m, f, fds)) < 0) {
a7556052 2873 m->n_reloading --;
a16e1123 2874 goto finish;
38c52d46 2875 }
a16e1123
LP
2876
2877 if (fseeko(f, 0, SEEK_SET) < 0) {
a7556052 2878 m->n_reloading --;
a16e1123
LP
2879 r = -errno;
2880 goto finish;
2881 }
2882
2883 /* From here on there is no way back. */
2884 manager_clear_jobs_and_units(m);
5a1e9937 2885 manager_undo_generators(m);
a16e1123 2886
2ded0c04 2887 /* Find new unit paths */
84e3543e 2888 lookup_paths_free(&m->lookup_paths);
c800e483 2889 if ((q = lookup_paths_init(&m->lookup_paths, m->running_as, true)) < 0)
2ded0c04
LP
2890 r = q;
2891
5a1e9937
LP
2892 manager_run_generators(m);
2893
2894 manager_build_unit_path_cache(m);
2895
a16e1123
LP
2896 /* First, enumerate what we can from all config files */
2897 if ((q = manager_enumerate(m)) < 0)
2898 r = q;
2899
2900 /* Second, deserialize our stored data */
2901 if ((q = manager_deserialize(m, f, fds)) < 0)
2902 r = q;
2903
2904 fclose(f);
2905 f = NULL;
2906
2907 /* Third, fire things up! */
2908 if ((q = manager_coldplug(m)) < 0)
2909 r = q;
2910
a7556052
LP
2911 assert(m->n_reloading > 0);
2912 m->n_reloading--;
9f611ad8 2913
a16e1123
LP
2914finish:
2915 if (f)
2916 fclose(f);
2917
2918 if (fds)
2919 fdset_free(fds);
2920
2921 return r;
2922}
2923
9e58ff9c
LP
2924bool manager_is_booting_or_shutting_down(Manager *m) {
2925 Unit *u;
2926
2927 assert(m);
2928
2929 /* Is the initial job still around? */
2930 if (manager_get_job(m, 1))
2931 return true;
2932
2933 /* Is there a job for the shutdown target? */
27d340c7
LP
2934 u = manager_get_unit(m, SPECIAL_SHUTDOWN_TARGET);
2935 if (u)
9e58ff9c
LP
2936 return !!u->meta.job;
2937
2938 return false;
2939}
2940
fdf20a31 2941void manager_reset_failed(Manager *m) {
5632e374
LP
2942 Unit *u;
2943 Iterator i;
2944
2945 assert(m);
2946
2947 HASHMAP_FOREACH(u, m->units, i)
fdf20a31 2948 unit_reset_failed(u);
5632e374
LP
2949}
2950
8f6df3fa
LP
2951bool manager_unit_pending_inactive(Manager *m, const char *name) {
2952 Unit *u;
2953
2954 assert(m);
2955 assert(name);
2956
2957 /* Returns true if the unit is inactive or going down */
8f6df3fa
LP
2958 if (!(u = manager_get_unit(m, name)))
2959 return true;
2960
18ffdfda 2961 return unit_pending_inactive(u);
8f6df3fa
LP
2962}
2963
b0c918b9 2964void manager_check_finished(Manager *m) {
e9ddabc2 2965 char userspace[FORMAT_TIMESPAN_MAX], initrd[FORMAT_TIMESPAN_MAX], kernel[FORMAT_TIMESPAN_MAX], sum[FORMAT_TIMESPAN_MAX];
18fa6b27 2966 usec_t kernel_usec = 0, initrd_usec = 0, userspace_usec = 0, total_usec = 0;
b0c918b9
LP
2967
2968 assert(m);
2969
2970 if (dual_timestamp_is_set(&m->finish_timestamp))
2971 return;
2972
2973 if (hashmap_size(m->jobs) > 0)
2974 return;
2975
2976 dual_timestamp_get(&m->finish_timestamp);
2977
e03ae661
LP
2978 if (m->running_as == MANAGER_SYSTEM && detect_container(NULL) <= 0) {
2979
18fa6b27
LP
2980 userspace_usec = m->finish_timestamp.monotonic - m->startup_timestamp.monotonic;
2981 total_usec = m->finish_timestamp.monotonic;
2982
e9ddabc2 2983 if (dual_timestamp_is_set(&m->initrd_timestamp)) {
18fa6b27
LP
2984
2985 kernel_usec = m->initrd_timestamp.monotonic;
2986 initrd_usec = m->startup_timestamp.monotonic - m->initrd_timestamp.monotonic;
2987
e9ddabc2 2988 log_info("Startup finished in %s (kernel) + %s (initrd) + %s (userspace) = %s.",
18fa6b27
LP
2989 format_timespan(kernel, sizeof(kernel), kernel_usec),
2990 format_timespan(initrd, sizeof(initrd), initrd_usec),
2991 format_timespan(userspace, sizeof(userspace), userspace_usec),
2992 format_timespan(sum, sizeof(sum), total_usec));
2993 } else {
2994 kernel_usec = m->startup_timestamp.monotonic;
2995 initrd_usec = 0;
2996
e9ddabc2 2997 log_info("Startup finished in %s (kernel) + %s (userspace) = %s.",
18fa6b27
LP
2998 format_timespan(kernel, sizeof(kernel), kernel_usec),
2999 format_timespan(userspace, sizeof(userspace), userspace_usec),
3000 format_timespan(sum, sizeof(sum), total_usec));
3001 }
3002 } else {
3003 userspace_usec = initrd_usec = kernel_usec = 0;
3004 total_usec = m->finish_timestamp.monotonic - m->startup_timestamp.monotonic;
3005
b0c918b9 3006 log_debug("Startup finished in %s.",
18fa6b27
LP
3007 format_timespan(sum, sizeof(sum), total_usec));
3008 }
b0c918b9 3009
18fa6b27 3010 bus_broadcast_finished(m, kernel_usec, initrd_usec, userspace_usec, total_usec);
530345e7
LP
3011
3012 sd_notifyf(false,
3013 "READY=1\nSTATUS=Startup finished in %s.",
3014 format_timespan(sum, sizeof(sum), total_usec));
b0c918b9
LP
3015}
3016
5a1e9937
LP
3017void manager_run_generators(Manager *m) {
3018 DIR *d = NULL;
5a1e9937 3019 const char *generator_path;
83cc030f 3020 const char *argv[3];
07f8a4aa 3021 mode_t u;
5a1e9937
LP
3022
3023 assert(m);
3024
af2d49f7 3025 generator_path = m->running_as == MANAGER_SYSTEM ? SYSTEM_GENERATOR_PATH : USER_GENERATOR_PATH;
5a1e9937
LP
3026 if (!(d = opendir(generator_path))) {
3027
3028 if (errno == ENOENT)
3029 return;
3030
3031 log_error("Failed to enumerate generator directory: %m");
3032 return;
3033 }
3034
3035 if (!m->generator_unit_path) {
f1d19aa4
LP
3036 const char *p;
3037 char user_path[] = "/tmp/systemd-generator-XXXXXX";
5a1e9937 3038
a08dab55 3039 if (m->running_as == MANAGER_SYSTEM && getpid() == 1) {
f1d19aa4
LP
3040 p = "/run/systemd/generator";
3041
3042 if (mkdir_p(p, 0755) < 0) {
3043 log_error("Failed to create generator directory: %m");
3044 goto finish;
3045 }
3046
3047 } else {
3048 if (!(p = mkdtemp(user_path))) {
3049 log_error("Failed to create generator directory: %m");
3050 goto finish;
3051 }
5a1e9937
LP
3052 }
3053
3054 if (!(m->generator_unit_path = strdup(p))) {
3055 log_error("Failed to allocate generator unit path.");
3056 goto finish;
3057 }
3058 }
3059
83cc030f
LP
3060 argv[0] = NULL; /* Leave this empty, execute_directory() will fill something in */
3061 argv[1] = m->generator_unit_path;
3062 argv[2] = NULL;
5a1e9937 3063
07f8a4aa 3064 u = umask(0022);
83cc030f 3065 execute_directory(generator_path, d, (char**) argv);
07f8a4aa 3066 umask(u);
5a1e9937
LP
3067
3068 if (rmdir(m->generator_unit_path) >= 0) {
3069 /* Uh? we were able to remove this dir? I guess that
3070 * means the directory was empty, hence let's shortcut
3071 * this */
3072
3073 free(m->generator_unit_path);
3074 m->generator_unit_path = NULL;
3075 goto finish;
3076 }
3077
3078 if (!strv_find(m->lookup_paths.unit_path, m->generator_unit_path)) {
3079 char **l;
3080
3081 if (!(l = strv_append(m->lookup_paths.unit_path, m->generator_unit_path))) {
3082 log_error("Failed to add generator directory to unit search path: %m");
3083 goto finish;
3084 }
3085
3086 strv_free(m->lookup_paths.unit_path);
3087 m->lookup_paths.unit_path = l;
7f4e0805
LP
3088
3089 log_debug("Added generator unit path %s to search path.", m->generator_unit_path);
5a1e9937
LP
3090 }
3091
3092finish:
3093 if (d)
3094 closedir(d);
5a1e9937
LP
3095}
3096
3097void manager_undo_generators(Manager *m) {
3098 assert(m);
3099
3100 if (!m->generator_unit_path)
3101 return;
3102
3103 strv_remove(m->lookup_paths.unit_path, m->generator_unit_path);
ad293f5a 3104 rm_rf(m->generator_unit_path, false, true, false);
5a1e9937
LP
3105
3106 free(m->generator_unit_path);
3107 m->generator_unit_path = NULL;
3108}
3109
06d4c99a
LP
3110int manager_set_default_controllers(Manager *m, char **controllers) {
3111 char **l;
3112
3113 assert(m);
3114
3115 if (!(l = strv_copy(controllers)))
3116 return -ENOMEM;
3117
3118 strv_free(m->default_controllers);
3119 m->default_controllers = l;
3120
3121 return 0;
3122}
3123
f1dd0c3f
LP
3124void manager_recheck_syslog(Manager *m) {
3125 Unit *u;
3126
3127 assert(m);
3128
3129 if (m->running_as != MANAGER_SYSTEM)
3130 return;
3131
3132 if ((u = manager_get_unit(m, SPECIAL_SYSLOG_SOCKET))) {
3133 SocketState state;
3134
3135 state = SOCKET(u)->state;
3136
3137 if (state != SOCKET_DEAD &&
3138 state != SOCKET_FAILED &&
3139 state != SOCKET_RUNNING) {
3140
3141 /* Hmm, the socket is not set up, or is still
3142 * listening, let's better not try to use
3143 * it. Note that we have no problem if the
3144 * socket is completely down, since there
3145 * might be a foreign /dev/log socket around
3146 * and we want to make use of that.
3147 */
3148
3149 log_close_syslog();
3150 return;
3151 }
3152 }
3153
3154 if ((u = manager_get_unit(m, SPECIAL_SYSLOG_TARGET)))
3155 if (TARGET(u)->state != TARGET_ACTIVE) {
3156 log_close_syslog();
3157 return;
3158 }
3159
3160 /* Hmm, OK, so the socket is either fully up, or fully down,
3161 * and the target is up, then let's make use of the socket */
3162 log_open();
3163}
3164
27d340c7
LP
3165void manager_set_show_status(Manager *m, bool b) {
3166 assert(m);
3167
3168 if (m->running_as != MANAGER_SYSTEM)
3169 return;
3170
3171 m->show_status = b;
3172
3173 if (b)
3174 touch("/run/systemd/show-status");
3175 else
3176 unlink("/run/systemd/show-status");
3177}
3178
3179bool manager_get_show_status(Manager *m) {
3180 assert(m);
3181
3182 if (m->running_as != MANAGER_SYSTEM)
3183 return false;
3184
3185 if (m->show_status)
3186 return true;
3187
3188 /* If Plymouth is running make sure we show the status, so
3189 * that there's something nice to see when people press Esc */
3190
3191 return plymouth_running();
3192}
3193
dfcd764e 3194static const char* const manager_running_as_table[_MANAGER_RUNNING_AS_MAX] = {
dfcd764e 3195 [MANAGER_SYSTEM] = "system",
af2d49f7 3196 [MANAGER_USER] = "user"
dfcd764e
LP
3197};
3198
3199DEFINE_STRING_TABLE_LOOKUP(manager_running_as, ManagerRunningAs);