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