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