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