]> git.ipfire.org Git - thirdparty/systemd.git/blame - src/manager.c
init: call telinit in case we are run as init and not pid1
[thirdparty/systemd.git] / src / manager.c
CommitLineData
60918275
LP
1/*-*- Mode: C; c-basic-offset: 8 -*-*/
2
a7334b09
LP
3/***
4 This file is part of systemd.
5
6 Copyright 2010 Lennart Poettering
7
8 systemd is free software; you can redistribute it and/or modify it
9 under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 2 of the License, or
11 (at your option) any later version.
12
13 systemd is distributed in the hope that it will be useful, but
14 WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 General Public License for more details.
17
18 You should have received a copy of the GNU General Public License
19 along with systemd; If not, see <http://www.gnu.org/licenses/>.
20***/
21
60918275
LP
22#include <assert.h>
23#include <errno.h>
87d1515d 24#include <string.h>
9152c765
LP
25#include <sys/epoll.h>
26#include <signal.h>
27#include <sys/signalfd.h>
28#include <sys/wait.h>
29#include <unistd.h>
e537352b 30#include <utmpx.h>
9152c765 31#include <sys/poll.h>
e1414003
LP
32#include <sys/reboot.h>
33#include <sys/ioctl.h>
34#include <linux/kd.h>
8e274523 35#include <libcgroup.h>
80876c20
LP
36#include <termios.h>
37#include <fcntl.h>
a16e1123
LP
38#include <sys/types.h>
39#include <sys/stat.h>
60918275
LP
40
41#include "manager.h"
42#include "hashmap.h"
43#include "macro.h"
44#include "strv.h"
16354eff 45#include "log.h"
2a987ee8 46#include "util.h"
ea430986 47#include "ratelimit.h"
8e274523
LP
48#include "cgroup.h"
49#include "mount-setup.h"
e537352b 50#include "utmp-wtmp.h"
9e2f7c11 51#include "unit-name.h"
4139c1b2
LP
52#include "dbus-unit.h"
53#include "dbus-job.h"
1137a57c 54#include "missing.h"
84e3543e 55#include "path-lookup.h"
514f4ef5 56#include "special.h"
60918275 57
701cc384
LP
58/* As soon as 16 units are in our GC queue, make sure to run a gc sweep */
59#define GC_QUEUE_ENTRIES_MAX 16
60
61/* As soon as 5s passed since a unit was added to our GC queue, make sure to run a gc sweep */
94b6dfa2 62#define GC_QUEUE_USEC_MAX (10*USEC_PER_SEC)
701cc384 63
8c47c732
LP
64/* Where clients shall send notification messages to */
65#define NOTIFY_SOCKET "/org/freedesktop/systemd1/notify"
66
67static int manager_setup_notify(Manager *m) {
68 union {
69 struct sockaddr sa;
70 struct sockaddr_un un;
71 } sa;
72 struct epoll_event ev;
73 char *ne[2], **t;
74 int one = 1;
75
76 assert(m);
77
78 m->notify_watch.type = WATCH_NOTIFY;
79 if ((m->notify_watch.fd = socket(AF_UNIX, SOCK_DGRAM|SOCK_CLOEXEC|SOCK_NONBLOCK, 0)) < 0) {
80 log_error("Failed to allocate notification socket: %m");
81 return -errno;
82 }
83
84 zero(sa);
85 sa.sa.sa_family = AF_UNIX;
86
87 if (m->running_as == MANAGER_SESSION)
88 snprintf(sa.un.sun_path+1, sizeof(sa.un.sun_path)-1, NOTIFY_SOCKET "/%llu", random_ull());
89 else
90 strncpy(sa.un.sun_path+1, NOTIFY_SOCKET, sizeof(sa.un.sun_path)-1);
91
92 if (bind(m->notify_watch.fd, &sa.sa, sizeof(sa)) < 0) {
93 log_error("bind() failed: %m");
94 return -errno;
95 }
96
97 if (setsockopt(m->notify_watch.fd, SOL_SOCKET, SO_PASSCRED, &one, sizeof(one)) < 0) {
98 log_error("SO_PASSCRED failed: %m");
99 return -errno;
100 }
101
102 zero(ev);
103 ev.events = EPOLLIN;
104 ev.data.ptr = &m->notify_watch;
105
106 if (epoll_ctl(m->epoll_fd, EPOLL_CTL_ADD, m->notify_watch.fd, &ev) < 0)
107 return -errno;
108
109 if (asprintf(&ne[0], "NOTIFY_SOCKET=@%s", sa.un.sun_path+1) < 0)
110 return -ENOMEM;
111
112 ne[1] = NULL;
5b6319dc 113 t = strv_env_merge(2, m->environment, ne);
8c47c732
LP
114 free(ne[0]);
115
116 if (!t)
117 return -ENOMEM;
118
119 strv_free(m->environment);
120 m->environment = t;
121
122 return 0;
123}
124
80876c20
LP
125static int enable_special_signals(Manager *m) {
126 char fd;
127
128 assert(m);
129
130 /* Enable that we get SIGINT on control-alt-del */
131 if (reboot(RB_DISABLE_CAD) < 0)
132 log_warning("Failed to enable ctrl-alt-del handling: %m");
133
affda787 134 if ((fd = open_terminal("/dev/tty0", O_RDWR|O_NOCTTY)) < 0)
80876c20
LP
135 log_warning("Failed to open /dev/tty0: %m");
136 else {
137 /* Enable that we get SIGWINCH on kbrequest */
138 if (ioctl(fd, KDSIGACCEPT, SIGWINCH) < 0)
139 log_warning("Failed to enable kbrequest handling: %s", strerror(errno));
140
141 close_nointr_nofail(fd);
142 }
143
144 return 0;
145}
146
ce578209 147static int manager_setup_signals(Manager *m) {
9152c765
LP
148 sigset_t mask;
149 struct epoll_event ev;
57c0c30e 150 struct sigaction sa;
60918275 151
ce578209
LP
152 assert(m);
153
57c0c30e
LP
154 /* We are not interested in SIGSTOP and friends. */
155 zero(sa);
156 sa.sa_handler = SIG_DFL;
157 sa.sa_flags = SA_NOCLDSTOP|SA_RESTART;
158 assert_se(sigaction(SIGCHLD, &sa, NULL) == 0);
159
ce578209 160 assert_se(sigemptyset(&mask) == 0);
7d793605
LP
161
162 sigset_add_many(&mask,
163 SIGCHLD, /* Child died */
164 SIGTERM, /* Reexecute daemon */
165 SIGHUP, /* Reload configuration */
166 SIGUSR1, /* systemd/upstart: reconnect to D-Bus */
167 SIGUSR2, /* systemd: dump status */
168 SIGINT, /* Kernel sends us this on control-alt-del */
169 SIGWINCH, /* Kernel sends us this on kbrequest (alt-arrowup) */
170 SIGPWR, /* Some kernel drivers and upsd send us this on power failure */
171 SIGRTMIN+0, /* systemd: start default.target */
172 SIGRTMIN+1, /* systemd: start rescue.target */
173 SIGRTMIN+2, /* systemd: isolate emergency.target */
174 SIGRTMIN+3, /* systemd: start halt.target */
175 SIGRTMIN+4, /* systemd: start poweroff.target */
176 SIGRTMIN+5, /* systemd: start reboot.target */
177 -1);
ce578209
LP
178 assert_se(sigprocmask(SIG_SETMASK, &mask, NULL) == 0);
179
ef734fd6 180 m->signal_watch.type = WATCH_SIGNAL;
ce578209
LP
181 if ((m->signal_watch.fd = signalfd(-1, &mask, SFD_NONBLOCK|SFD_CLOEXEC)) < 0)
182 return -errno;
183
184 zero(ev);
185 ev.events = EPOLLIN;
186 ev.data.ptr = &m->signal_watch;
187
188 if (epoll_ctl(m->epoll_fd, EPOLL_CTL_ADD, m->signal_watch.fd, &ev) < 0)
189 return -errno;
190
80876c20
LP
191 if (m->running_as == MANAGER_INIT)
192 return enable_special_signals(m);
e1414003 193
ce578209
LP
194 return 0;
195}
196
80876c20 197int manager_new(ManagerRunningAs running_as, bool confirm_spawn, Manager **_m) {
ce578209 198 Manager *m;
8e274523
LP
199 int r = -ENOMEM;
200
201 assert(_m);
a5dab5ce
LP
202 assert(running_as >= 0);
203 assert(running_as < _MANAGER_RUNNING_AS_MAX);
ce578209 204
60918275 205 if (!(m = new0(Manager, 1)))
8e274523 206 return -ENOMEM;
60918275 207
871d7de4 208 timestamp_get(&m->startup_timestamp);
e537352b 209
a5dab5ce 210 m->running_as = running_as;
80876c20 211 m->confirm_spawn = confirm_spawn;
05e343b7 212 m->name_data_slot = -1;
a16e1123 213 m->exit_code = _MANAGER_EXIT_CODE_INVALID;
80876c20 214
8d567588 215 m->signal_watch.fd = m->mount_watch.fd = m->udev_watch.fd = m->epoll_fd = m->dev_autofs_fd = -1;
ea430986 216 m->current_job_id = 1; /* start as id #1, so that we can leave #0 around as "null-like" value */
9152c765 217
1137a57c
LP
218 if (!(m->environment = strv_copy(environ)))
219 goto fail;
220
87f0e418 221 if (!(m->units = hashmap_new(string_hash_func, string_compare_func)))
60918275
LP
222 goto fail;
223
224 if (!(m->jobs = hashmap_new(trivial_hash_func, trivial_compare_func)))
225 goto fail;
226
e5b5ae50 227 if (!(m->transaction_jobs = hashmap_new(trivial_hash_func, trivial_compare_func)))
60918275
LP
228 goto fail;
229
9152c765
LP
230 if (!(m->watch_pids = hashmap_new(trivial_hash_func, trivial_compare_func)))
231 goto fail;
232
8e274523
LP
233 if (!(m->cgroup_bondings = hashmap_new(string_hash_func, string_compare_func)))
234 goto fail;
235
05e343b7
LP
236 if (!(m->watch_bus = hashmap_new(string_hash_func, string_compare_func)))
237 goto fail;
238
9152c765
LP
239 if ((m->epoll_fd = epoll_create1(EPOLL_CLOEXEC)) < 0)
240 goto fail;
241
84e3543e 242 if ((r = lookup_paths_init(&m->lookup_paths, m->running_as)) < 0)
e1414003
LP
243 goto fail;
244
8e274523
LP
245 if ((r = manager_setup_signals(m)) < 0)
246 goto fail;
247
8e274523 248 if ((r = manager_setup_cgroup(m)) < 0)
9152c765
LP
249 goto fail;
250
8c47c732
LP
251 if ((r = manager_setup_notify(m)) < 0)
252 goto fail;
253
f278026d
LP
254 /* Try to connect to the busses, if possible. */
255 if ((r = bus_init_system(m)) < 0 ||
256 (r = bus_init_api(m)) < 0)
ea430986
LP
257 goto fail;
258
8e274523
LP
259 *_m = m;
260 return 0;
60918275
LP
261
262fail:
263 manager_free(m);
8e274523 264 return r;
60918275
LP
265}
266
23a177ef
LP
267static unsigned manager_dispatch_cleanup_queue(Manager *m) {
268 Meta *meta;
269 unsigned n = 0;
270
271 assert(m);
272
273 while ((meta = m->cleanup_queue)) {
274 assert(meta->in_cleanup_queue);
275
276 unit_free(UNIT(meta));
277 n++;
278 }
279
280 return n;
281}
282
eced69b3
LP
283enum {
284 GC_OFFSET_IN_PATH, /* This one is on the path we were travelling */
285 GC_OFFSET_UNSURE, /* No clue */
286 GC_OFFSET_GOOD, /* We still need this unit */
287 GC_OFFSET_BAD, /* We don't need this unit anymore */
288 _GC_OFFSET_MAX
289};
290
291static void unit_gc_sweep(Unit *u, unsigned gc_marker) {
701cc384
LP
292 Iterator i;
293 Unit *other;
eced69b3 294 bool is_bad;
701cc384
LP
295
296 assert(u);
297
eced69b3
LP
298 if (u->meta.gc_marker == gc_marker + GC_OFFSET_GOOD ||
299 u->meta.gc_marker == gc_marker + GC_OFFSET_BAD ||
300 u->meta.gc_marker == gc_marker + GC_OFFSET_IN_PATH)
701cc384
LP
301 return;
302
c9c0cadb 303 if (u->meta.in_cleanup_queue)
701cc384
LP
304 goto bad;
305
306 if (unit_check_gc(u))
307 goto good;
308
eced69b3
LP
309 u->meta.gc_marker = gc_marker + GC_OFFSET_IN_PATH;
310
311 is_bad = true;
312
701cc384
LP
313 SET_FOREACH(other, u->meta.dependencies[UNIT_REFERENCED_BY], i) {
314 unit_gc_sweep(other, gc_marker);
315
eced69b3 316 if (other->meta.gc_marker == gc_marker + GC_OFFSET_GOOD)
701cc384 317 goto good;
eced69b3
LP
318
319 if (other->meta.gc_marker != gc_marker + GC_OFFSET_BAD)
320 is_bad = false;
701cc384
LP
321 }
322
eced69b3
LP
323 if (is_bad)
324 goto bad;
325
326 /* We were unable to find anything out about this entry, so
327 * let's investigate it later */
328 u->meta.gc_marker = gc_marker + GC_OFFSET_UNSURE;
329 unit_add_to_gc_queue(u);
330 return;
331
701cc384 332bad:
eced69b3
LP
333 /* We definitely know that this one is not useful anymore, so
334 * let's mark it for deletion */
335 u->meta.gc_marker = gc_marker + GC_OFFSET_BAD;
336 unit_add_to_cleanup_queue(u);
701cc384
LP
337 return;
338
339good:
eced69b3 340 u->meta.gc_marker = gc_marker + GC_OFFSET_GOOD;
701cc384
LP
341}
342
343static unsigned manager_dispatch_gc_queue(Manager *m) {
344 Meta *meta;
345 unsigned n = 0;
eced69b3 346 unsigned gc_marker;
701cc384
LP
347
348 assert(m);
349
350 if ((m->n_in_gc_queue < GC_QUEUE_ENTRIES_MAX) &&
351 (m->gc_queue_timestamp <= 0 ||
352 (m->gc_queue_timestamp + GC_QUEUE_USEC_MAX) > now(CLOCK_MONOTONIC)))
353 return 0;
354
355 log_debug("Running GC...");
356
eced69b3
LP
357 m->gc_marker += _GC_OFFSET_MAX;
358 if (m->gc_marker + _GC_OFFSET_MAX <= _GC_OFFSET_MAX)
c9c0cadb 359 m->gc_marker = 1;
701cc384 360
eced69b3
LP
361 gc_marker = m->gc_marker;
362
701cc384
LP
363 while ((meta = m->gc_queue)) {
364 assert(meta->in_gc_queue);
365
eced69b3
LP
366 unit_gc_sweep(UNIT(meta), gc_marker);
367
701cc384
LP
368 LIST_REMOVE(Meta, gc_queue, m->gc_queue, meta);
369 meta->in_gc_queue = false;
370
371 n++;
372
eced69b3
LP
373 if (meta->gc_marker == gc_marker + GC_OFFSET_BAD ||
374 meta->gc_marker == gc_marker + GC_OFFSET_UNSURE) {
701cc384 375 log_debug("Collecting %s", meta->id);
eced69b3 376 meta->gc_marker = gc_marker + GC_OFFSET_BAD;
701cc384
LP
377 unit_add_to_cleanup_queue(UNIT(meta));
378 }
379 }
380
381 m->n_in_gc_queue = 0;
382 m->gc_queue_timestamp = 0;
383
384 return n;
385}
386
a16e1123 387static void manager_clear_jobs_and_units(Manager *m) {
e5b5ae50 388 Job *j;
a16e1123 389 Unit *u;
60918275
LP
390
391 assert(m);
392
87f0e418 393 while ((j = hashmap_first(m->transaction_jobs)))
e5b5ae50
LP
394 job_free(j);
395
87f0e418
LP
396 while ((u = hashmap_first(m->units)))
397 unit_free(u);
964e0949
LP
398
399 manager_dispatch_cleanup_queue(m);
400
401 assert(!m->load_queue);
402 assert(!m->run_queue);
403 assert(!m->dbus_unit_queue);
404 assert(!m->dbus_job_queue);
405 assert(!m->cleanup_queue);
406 assert(!m->gc_queue);
407
408 assert(hashmap_isempty(m->transaction_jobs));
409 assert(hashmap_isempty(m->jobs));
410 assert(hashmap_isempty(m->units));
a16e1123
LP
411}
412
413void manager_free(Manager *m) {
414 UnitType c;
87f0e418 415
a16e1123
LP
416 assert(m);
417
418 manager_clear_jobs_and_units(m);
23a177ef 419
7824bbeb
LP
420 for (c = 0; c < _UNIT_TYPE_MAX; c++)
421 if (unit_vtable[c]->shutdown)
422 unit_vtable[c]->shutdown(m);
423
a16e1123
LP
424 /* If we reexecute ourselves, we keep the root cgroup
425 * around */
426 manager_shutdown_cgroup(m, m->exit_code != MANAGER_REEXECUTE);
8e274523 427
f278026d
LP
428 bus_done_api(m);
429 bus_done_system(m);
ea430986 430
87f0e418 431 hashmap_free(m->units);
60918275 432 hashmap_free(m->jobs);
e5b5ae50 433 hashmap_free(m->transaction_jobs);
9152c765 434 hashmap_free(m->watch_pids);
05e343b7 435 hashmap_free(m->watch_bus);
9152c765
LP
436
437 if (m->epoll_fd >= 0)
a16e1123 438 close_nointr_nofail(m->epoll_fd);
acbb0225 439 if (m->signal_watch.fd >= 0)
a16e1123 440 close_nointr_nofail(m->signal_watch.fd);
8c47c732
LP
441 if (m->notify_watch.fd >= 0)
442 close_nointr_nofail(m->notify_watch.fd);
60918275 443
84e3543e 444 lookup_paths_free(&m->lookup_paths);
1137a57c 445 strv_free(m->environment);
036643a2 446
8e274523
LP
447 free(m->cgroup_controller);
448 free(m->cgroup_hierarchy);
449
8e274523
LP
450 hashmap_free(m->cgroup_bondings);
451
60918275
LP
452 free(m);
453}
454
a16e1123
LP
455int manager_enumerate(Manager *m) {
456 int r = 0, q;
f50e0a01 457 UnitType c;
f50e0a01
LP
458
459 assert(m);
460
a16e1123
LP
461 /* Let's ask every type to load all units from disk/kernel
462 * that it might know */
f50e0a01
LP
463 for (c = 0; c < _UNIT_TYPE_MAX; c++)
464 if (unit_vtable[c]->enumerate)
a16e1123
LP
465 if ((q = unit_vtable[c]->enumerate(m)) < 0)
466 r = q;
f50e0a01
LP
467
468 manager_dispatch_load_queue(m);
a16e1123
LP
469 return r;
470}
471
472int manager_coldplug(Manager *m) {
473 int r = 0, q;
474 Iterator i;
475 Unit *u;
476 char *k;
477
478 assert(m);
f50e0a01
LP
479
480 /* Then, let's set up their initial state. */
481 HASHMAP_FOREACH_KEY(u, k, m->units, i) {
482
483 /* ignore aliases */
9e2f7c11 484 if (u->meta.id != k)
f50e0a01
LP
485 continue;
486
cca098b0
LP
487 if ((q = unit_coldplug(u)) < 0)
488 r = q;
f50e0a01
LP
489 }
490
a16e1123
LP
491 return r;
492}
493
494int manager_startup(Manager *m, FILE *serialization, FDSet *fds) {
495 int r, q;
496
497 assert(m);
498
499 /* First, enumerate what we can from all config files */
500 r = manager_enumerate(m);
501
502 /* Second, deserialize if there is something to deserialize */
503 if (serialization)
504 if ((q = manager_deserialize(m, serialization, fds)) < 0)
505 r = q;
506
507 /* Third, fire things up! */
508 if ((q = manager_coldplug(m)) < 0)
509 r = q;
510
e537352b
LP
511 /* Now that the initial devices are available, let's see if we
512 * can write the utmp file */
513 manager_write_utmp_reboot(m);
514
a16e1123 515 return r;
f50e0a01
LP
516}
517
23a177ef 518static void transaction_delete_job(Manager *m, Job *j, bool delete_dependencies) {
302d0040
LP
519 assert(m);
520 assert(j);
521
1ffba6fe
LP
522 /* Deletes one job from the transaction */
523
23a177ef 524 manager_transaction_unlink_job(m, j, delete_dependencies);
302d0040 525
ac1135be 526 if (!j->installed)
302d0040
LP
527 job_free(j);
528}
529
87f0e418 530static void transaction_delete_unit(Manager *m, Unit *u) {
1ffba6fe
LP
531 Job *j;
532
87f0e418 533 /* Deletes all jobs associated with a certain unit from the
1ffba6fe
LP
534 * transaction */
535
87f0e418 536 while ((j = hashmap_get(m->transaction_jobs, u)))
23a177ef 537 transaction_delete_job(m, j, true);
1ffba6fe
LP
538}
539
f04fa1d5
LP
540static void transaction_clean_dependencies(Manager *m) {
541 Iterator i;
542 Job *j;
543
544 assert(m);
545
546 /* Drops all dependencies of all installed jobs */
547
548 HASHMAP_FOREACH(j, m->jobs, i) {
549 while (j->subject_list)
550 job_dependency_free(j->subject_list);
551 while (j->object_list)
552 job_dependency_free(j->object_list);
553 }
554
555 assert(!m->transaction_anchor);
556}
557
11dd41ce
LP
558static void transaction_abort(Manager *m) {
559 Job *j;
560
561 assert(m);
11dd41ce 562
e5b5ae50 563 while ((j = hashmap_first(m->transaction_jobs)))
ac1135be 564 if (j->installed)
23a177ef 565 transaction_delete_job(m, j, true);
e5b5ae50
LP
566 else
567 job_free(j);
568
569 assert(hashmap_isempty(m->transaction_jobs));
f04fa1d5
LP
570
571 transaction_clean_dependencies(m);
e5b5ae50
LP
572}
573
574static void transaction_find_jobs_that_matter_to_anchor(Manager *m, Job *j, unsigned generation) {
575 JobDependency *l;
576
577 assert(m);
578
87f0e418 579 /* A recursive sweep through the graph that marks all units
1ffba6fe
LP
580 * that matter to the anchor job, i.e. are directly or
581 * indirectly a dependency of the anchor job via paths that
582 * are fully marked as mattering. */
583
44d8db9e
LP
584 if (j)
585 l = j->subject_list;
586 else
587 l = m->transaction_anchor;
588
589 LIST_FOREACH(subject, l, l) {
e5b5ae50
LP
590
591 /* This link does not matter */
592 if (!l->matters)
593 continue;
594
87f0e418 595 /* This unit has already been marked */
e5b5ae50
LP
596 if (l->object->generation == generation)
597 continue;
598
599 l->object->matters_to_anchor = true;
600 l->object->generation = generation;
601
602 transaction_find_jobs_that_matter_to_anchor(m, l->object, generation);
603 }
604}
605
7fad411c 606static void transaction_merge_and_delete_job(Manager *m, Job *j, Job *other, JobType t) {
e5b5ae50
LP
607 JobDependency *l, *last;
608
609 assert(j);
610 assert(other);
87f0e418 611 assert(j->unit == other->unit);
ac1135be 612 assert(!j->installed);
e5b5ae50 613
1ffba6fe
LP
614 /* Merges 'other' into 'j' and then deletes j. */
615
e5b5ae50
LP
616 j->type = t;
617 j->state = JOB_WAITING;
9e2f7c11 618 j->override = j->override || other->override;
e5b5ae50
LP
619
620 j->matters_to_anchor = j->matters_to_anchor || other->matters_to_anchor;
621
622 /* Patch us in as new owner of the JobDependency objects */
623 last = NULL;
44d8db9e 624 LIST_FOREACH(subject, l, other->subject_list) {
e5b5ae50
LP
625 assert(l->subject == other);
626 l->subject = j;
627 last = l;
628 }
629
630 /* Merge both lists */
631 if (last) {
632 last->subject_next = j->subject_list;
633 if (j->subject_list)
634 j->subject_list->subject_prev = last;
635 j->subject_list = other->subject_list;
636 }
637
638 /* Patch us in as new owner of the JobDependency objects */
639 last = NULL;
44d8db9e 640 LIST_FOREACH(object, l, other->object_list) {
e5b5ae50
LP
641 assert(l->object == other);
642 l->object = j;
643 last = l;
644 }
645
646 /* Merge both lists */
647 if (last) {
648 last->object_next = j->object_list;
649 if (j->object_list)
650 j->object_list->object_prev = last;
651 j->object_list = other->object_list;
652 }
653
e5b5ae50
LP
654 /* Kill the other job */
655 other->subject_list = NULL;
656 other->object_list = NULL;
23a177ef 657 transaction_delete_job(m, other, true);
e5b5ae50
LP
658}
659
5cb5a6ff 660static int delete_one_unmergeable_job(Manager *m, Job *j) {
1ffba6fe
LP
661 Job *k;
662
663 assert(j);
664
665 /* Tries to delete one item in the linked list
666 * j->transaction_next->transaction_next->... that conflicts
667 * whith another one, in an attempt to make an inconsistent
668 * transaction work. */
669
670 /* We rely here on the fact that if a merged with b does not
671 * merge with c, either a or b merge with c neither */
034c6ed7
LP
672 LIST_FOREACH(transaction, j, j)
673 LIST_FOREACH(transaction, k, j->transaction_next) {
1ffba6fe
LP
674 Job *d;
675
676 /* Is this one mergeable? Then skip it */
5cb5a6ff 677 if (job_type_is_mergeable(j->type, k->type))
1ffba6fe
LP
678 continue;
679
680 /* Ok, we found two that conflict, let's see if we can
681 * drop one of them */
682 if (!j->matters_to_anchor)
683 d = j;
684 else if (!k->matters_to_anchor)
685 d = k;
686 else
687 return -ENOEXEC;
688
689 /* Ok, we can drop one, so let's do so. */
9e2f7c11 690 log_debug("Trying to fix job merging by deleting job %s/%s", d->unit->meta.id, job_type_to_string(d->type));
23a177ef 691 transaction_delete_job(m, d, true);
1ffba6fe
LP
692 return 0;
693 }
694
695 return -EINVAL;
696}
697
e5b5ae50 698static int transaction_merge_jobs(Manager *m) {
11dd41ce 699 Job *j;
034c6ed7 700 Iterator i;
e5b5ae50
LP
701 int r;
702
703 assert(m);
704
1ffba6fe
LP
705 /* First step, check whether any of the jobs for one specific
706 * task conflict. If so, try to drop one of them. */
034c6ed7 707 HASHMAP_FOREACH(j, m->transaction_jobs, i) {
1ffba6fe
LP
708 JobType t;
709 Job *k;
710
711 t = j->type;
034c6ed7 712 LIST_FOREACH(transaction, k, j->transaction_next) {
1ffba6fe
LP
713 if ((r = job_type_merge(&t, k->type)) >= 0)
714 continue;
715
716 /* OK, we could not merge all jobs for this
717 * action. Let's see if we can get rid of one
718 * of them */
719
5cb5a6ff 720 if ((r = delete_one_unmergeable_job(m, j)) >= 0)
1ffba6fe
LP
721 /* Ok, we managed to drop one, now
722 * let's ask our callers to call us
723 * again after garbage collecting */
724 return -EAGAIN;
725
726 /* We couldn't merge anything. Failure */
727 return r;
728 }
729 }
730
731 /* Second step, merge the jobs. */
034c6ed7 732 HASHMAP_FOREACH(j, m->transaction_jobs, i) {
e5b5ae50
LP
733 JobType t = j->type;
734 Job *k;
735
e094e853 736 /* Merge all transactions */
034c6ed7 737 LIST_FOREACH(transaction, k, j->transaction_next)
1ffba6fe 738 assert_se(job_type_merge(&t, k->type) == 0);
e5b5ae50 739
5cb5a6ff 740 /* If an active job is mergeable, merge it too */
87f0e418
LP
741 if (j->unit->meta.job)
742 job_type_merge(&t, j->unit->meta.job->type); /* Might fail. Which is OK */
e094e853 743
e5b5ae50 744 while ((k = j->transaction_next)) {
ac1135be 745 if (j->installed) {
7fad411c 746 transaction_merge_and_delete_job(m, k, j, t);
e5b5ae50
LP
747 j = k;
748 } else
7fad411c 749 transaction_merge_and_delete_job(m, j, k, t);
e5b5ae50
LP
750 }
751
752 assert(!j->transaction_next);
753 assert(!j->transaction_prev);
754 }
755
7fad411c 756 return 0;
e5b5ae50
LP
757}
758
23a177ef
LP
759static void transaction_drop_redundant(Manager *m) {
760 bool again;
761
762 assert(m);
763
764 /* Goes through the transaction and removes all jobs that are
765 * a noop */
766
767 do {
768 Job *j;
769 Iterator i;
770
771 again = false;
772
773 HASHMAP_FOREACH(j, m->transaction_jobs, i) {
774 bool changes_something = false;
775 Job *k;
776
777 LIST_FOREACH(transaction, k, j) {
778
779 if (!job_is_anchor(k) &&
780 job_type_is_redundant(k->type, unit_active_state(k->unit)))
781 continue;
782
783 changes_something = true;
784 break;
785 }
786
787 if (changes_something)
788 continue;
789
9e2f7c11 790 log_debug("Found redundant job %s/%s, dropping.", j->unit->meta.id, job_type_to_string(j->type));
23a177ef
LP
791 transaction_delete_job(m, j, false);
792 again = true;
793 break;
794 }
795
796 } while (again);
797}
798
87f0e418
LP
799static bool unit_matters_to_anchor(Unit *u, Job *j) {
800 assert(u);
1ffba6fe
LP
801 assert(!j->transaction_prev);
802
87f0e418 803 /* Checks whether at least one of the jobs for this unit
1ffba6fe
LP
804 * matters to the anchor. */
805
034c6ed7 806 LIST_FOREACH(transaction, j, j)
1ffba6fe
LP
807 if (j->matters_to_anchor)
808 return true;
809
810 return false;
811}
812
e5b5ae50 813static int transaction_verify_order_one(Manager *m, Job *j, Job *from, unsigned generation) {
034c6ed7 814 Iterator i;
87f0e418 815 Unit *u;
11dd41ce 816 int r;
e5b5ae50
LP
817
818 assert(m);
819 assert(j);
1ffba6fe
LP
820 assert(!j->transaction_prev);
821
822 /* Does a recursive sweep through the ordering graph, looking
823 * for a cycle. If we find cycle we try to break it. */
e5b5ae50 824
23e3c588
LP
825 /* Have we seen this before? */
826 if (j->generation == generation) {
e5b5ae50
LP
827 Job *k;
828
23e3c588
LP
829 /* If the marker is NULL we have been here already and
830 * decided the job was loop-free from here. Hence
831 * shortcut things and return right-away. */
832 if (!j->marker)
833 return 0;
e5b5ae50 834
23e3c588
LP
835 /* So, the marker is not NULL and we already have been
836 * here. We have a cycle. Let's try to break it. We go
837 * backwards in our path and try to find a suitable
838 * job to remove. We use the marker to find our way
839 * back, since smart how we are we stored our way back
840 * in there. */
9e2f7c11 841 log_debug("Found ordering cycle on %s/%s", j->unit->meta.id, job_type_to_string(j->type));
9f04bd52 842
23e3c588 843 for (k = from; k; k = ((k->generation == generation && k->marker != k) ? k->marker : NULL)) {
1ffba6fe 844
9e2f7c11 845 log_debug("Walked on cycle path to %s/%s", k->unit->meta.id, job_type_to_string(k->type));
9f04bd52 846
ac1135be 847 if (!k->installed &&
87f0e418 848 !unit_matters_to_anchor(k->unit, k)) {
1ffba6fe
LP
849 /* Ok, we can drop this one, so let's
850 * do so. */
9e2f7c11 851 log_debug("Breaking order cycle by deleting job %s/%s", k->unit->meta.id, job_type_to_string(k->type));
87f0e418 852 transaction_delete_unit(m, k->unit);
e5b5ae50
LP
853 return -EAGAIN;
854 }
855
856 /* Check if this in fact was the beginning of
7fad411c 857 * the cycle */
e5b5ae50
LP
858 if (k == j)
859 break;
860 }
861
9f04bd52
LP
862 log_debug("Unable to break cycle");
863
1ffba6fe 864 return -ENOEXEC;
e5b5ae50
LP
865 }
866
1ffba6fe 867 /* Make the marker point to where we come from, so that we can
23e3c588
LP
868 * find our way backwards if we want to break a cycle. We use
869 * a special marker for the beginning: we point to
870 * ourselves. */
871 j->marker = from ? from : j;
e5b5ae50
LP
872 j->generation = generation;
873
1ffba6fe 874 /* We assume that the the dependencies are bidirectional, and
87f0e418
LP
875 * hence can ignore UNIT_AFTER */
876 SET_FOREACH(u, j->unit->meta.dependencies[UNIT_BEFORE], i) {
e5b5ae50
LP
877 Job *o;
878
87f0e418
LP
879 /* Is there a job for this unit? */
880 if (!(o = hashmap_get(m->transaction_jobs, u)))
1ffba6fe
LP
881
882 /* Ok, there is no job for this in the
883 * transaction, but maybe there is already one
884 * running? */
87f0e418 885 if (!(o = u->meta.job))
e5b5ae50
LP
886 continue;
887
888 if ((r = transaction_verify_order_one(m, o, j, generation)) < 0)
889 return r;
890 }
891
9f04bd52
LP
892 /* Ok, let's backtrack, and remember that this entry is not on
893 * our path anymore. */
894 j->marker = NULL;
895
e5b5ae50
LP
896 return 0;
897}
898
899static int transaction_verify_order(Manager *m, unsigned *generation) {
1ffba6fe
LP
900 Job *j;
901 int r;
034c6ed7 902 Iterator i;
23e3c588 903 unsigned g;
1ffba6fe 904
e5b5ae50
LP
905 assert(m);
906 assert(generation);
907
1ffba6fe
LP
908 /* Check if the ordering graph is cyclic. If it is, try to fix
909 * that up by dropping one of the jobs. */
e5b5ae50 910
23e3c588
LP
911 g = (*generation)++;
912
034c6ed7 913 HASHMAP_FOREACH(j, m->transaction_jobs, i)
23e3c588 914 if ((r = transaction_verify_order_one(m, j, NULL, g)) < 0)
1ffba6fe 915 return r;
e5b5ae50
LP
916
917 return 0;
918}
919
920static void transaction_collect_garbage(Manager *m) {
921 bool again;
922
923 assert(m);
924
1ffba6fe
LP
925 /* Drop jobs that are not required by any other job */
926
e5b5ae50 927 do {
034c6ed7 928 Iterator i;
e5b5ae50
LP
929 Job *j;
930
931 again = false;
932
034c6ed7 933 HASHMAP_FOREACH(j, m->transaction_jobs, i) {
e5b5ae50
LP
934 if (j->object_list)
935 continue;
936
9e2f7c11 937 log_debug("Garbage collecting job %s/%s", j->unit->meta.id, job_type_to_string(j->type));
23a177ef 938 transaction_delete_job(m, j, true);
e5b5ae50
LP
939 again = true;
940 break;
941 }
942
943 } while (again);
944}
945
c497c7a9 946static int transaction_is_destructive(Manager *m) {
034c6ed7 947 Iterator i;
e5b5ae50 948 Job *j;
11dd41ce
LP
949
950 assert(m);
11dd41ce 951
e5b5ae50
LP
952 /* Checks whether applying this transaction means that
953 * existing jobs would be replaced */
11dd41ce 954
034c6ed7 955 HASHMAP_FOREACH(j, m->transaction_jobs, i) {
e094e853
LP
956
957 /* Assume merged */
958 assert(!j->transaction_prev);
959 assert(!j->transaction_next);
960
87f0e418
LP
961 if (j->unit->meta.job &&
962 j->unit->meta.job != j &&
963 !job_type_is_superset(j->type, j->unit->meta.job->type))
e5b5ae50 964 return -EEXIST;
e094e853 965 }
11dd41ce 966
e5b5ae50
LP
967 return 0;
968}
969
e094e853
LP
970static void transaction_minimize_impact(Manager *m) {
971 bool again;
972 assert(m);
973
974 /* Drops all unnecessary jobs that reverse already active jobs
975 * or that stop a running service. */
976
977 do {
978 Job *j;
034c6ed7 979 Iterator i;
e094e853
LP
980
981 again = false;
982
034c6ed7
LP
983 HASHMAP_FOREACH(j, m->transaction_jobs, i) {
984 LIST_FOREACH(transaction, j, j) {
c20cae32 985 bool stops_running_service, changes_existing_job;
e094e853
LP
986
987 /* If it matters, we shouldn't drop it */
988 if (j->matters_to_anchor)
989 continue;
990
991 /* Would this stop a running service?
992 * Would this change an existing job?
993 * If so, let's drop this entry */
c20cae32
LP
994
995 stops_running_service =
996 j->type == JOB_STOP && UNIT_IS_ACTIVE_OR_ACTIVATING(unit_active_state(j->unit));
997
998 changes_existing_job =
999 j->unit->meta.job && job_type_is_conflicting(j->type, j->unit->meta.job->state);
1000
1001 if (!stops_running_service && !changes_existing_job)
e094e853
LP
1002 continue;
1003
c20cae32 1004 if (stops_running_service)
9e2f7c11 1005 log_debug("%s/%s would stop a running service.", j->unit->meta.id, job_type_to_string(j->type));
c20cae32
LP
1006
1007 if (changes_existing_job)
9e2f7c11 1008 log_debug("%s/%s would change existing job.", j->unit->meta.id, job_type_to_string(j->type));
c20cae32 1009
e094e853 1010 /* Ok, let's get rid of this */
9e2f7c11 1011 log_debug("Deleting %s/%s to minimize impact.", j->unit->meta.id, job_type_to_string(j->type));
c20cae32 1012
23a177ef 1013 transaction_delete_job(m, j, true);
e094e853
LP
1014 again = true;
1015 break;
1016 }
1017
1018 if (again)
1019 break;
1020 }
1021
1022 } while (again);
1023}
1024
c497c7a9 1025static int transaction_apply(Manager *m) {
034c6ed7 1026 Iterator i;
e5b5ae50
LP
1027 Job *j;
1028 int r;
1029
1ffba6fe
LP
1030 /* Moves the transaction jobs to the set of active jobs */
1031
034c6ed7 1032 HASHMAP_FOREACH(j, m->transaction_jobs, i) {
e094e853
LP
1033 /* Assume merged */
1034 assert(!j->transaction_prev);
1035 assert(!j->transaction_next);
1036
ac1135be 1037 if (j->installed)
e5b5ae50
LP
1038 continue;
1039
1040 if ((r = hashmap_put(m->jobs, UINT32_TO_PTR(j->id), j)) < 0)
11dd41ce
LP
1041 goto rollback;
1042 }
1043
e5b5ae50 1044 while ((j = hashmap_steal_first(m->transaction_jobs))) {
ac1135be 1045 if (j->installed)
e5b5ae50
LP
1046 continue;
1047
87f0e418
LP
1048 if (j->unit->meta.job)
1049 job_free(j->unit->meta.job);
11dd41ce 1050
87f0e418 1051 j->unit->meta.job = j;
ac1135be 1052 j->installed = true;
11dd41ce 1053
e5b5ae50
LP
1054 /* We're fully installed. Now let's free data we don't
1055 * need anymore. */
1056
1057 assert(!j->transaction_next);
1058 assert(!j->transaction_prev);
1059
c1e1601e
LP
1060 job_add_to_run_queue(j);
1061 job_add_to_dbus_queue(j);
01184e04
LP
1062 }
1063
1064 /* As last step, kill all remaining job dependencies. */
f04fa1d5 1065 transaction_clean_dependencies(m);
1ffba6fe 1066
11dd41ce
LP
1067 return 0;
1068
1069rollback:
1070
034c6ed7 1071 HASHMAP_FOREACH(j, m->transaction_jobs, i) {
ac1135be 1072 if (j->installed)
e5b5ae50
LP
1073 continue;
1074
1075 hashmap_remove(m->jobs, UINT32_TO_PTR(j->id));
1076 }
1077
1078 return r;
1079}
1080
e5b5ae50
LP
1081static int transaction_activate(Manager *m, JobMode mode) {
1082 int r;
1083 unsigned generation = 1;
1084
1085 assert(m);
1086
1087 /* This applies the changes recorded in transaction_jobs to
1088 * the actual list of jobs, if possible. */
1089
1090 /* First step: figure out which jobs matter */
1091 transaction_find_jobs_that_matter_to_anchor(m, NULL, generation++);
1092
e094e853
LP
1093 /* Second step: Try not to stop any running services if
1094 * we don't have to. Don't try to reverse running
1095 * jobs if we don't have to. */
1096 transaction_minimize_impact(m);
1097
23a177ef
LP
1098 /* Third step: Drop redundant jobs */
1099 transaction_drop_redundant(m);
1100
1ffba6fe 1101 for (;;) {
23a177ef 1102 /* Fourth step: Let's remove unneeded jobs that might
1ffba6fe
LP
1103 * be lurking. */
1104 transaction_collect_garbage(m);
e5b5ae50 1105
23a177ef 1106 /* Fifth step: verify order makes sense and correct
1ffba6fe
LP
1107 * cycles if necessary and possible */
1108 if ((r = transaction_verify_order(m, &generation)) >= 0)
1109 break;
e5b5ae50 1110
9f04bd52
LP
1111 if (r != -EAGAIN) {
1112 log_debug("Requested transaction contains an unfixable cyclic ordering dependency: %s", strerror(-r));
1ffba6fe 1113 goto rollback;
9f04bd52 1114 }
e5b5ae50 1115
1ffba6fe
LP
1116 /* Let's see if the resulting transaction ordering
1117 * graph is still cyclic... */
1118 }
1119
1120 for (;;) {
23a177ef 1121 /* Sixth step: let's drop unmergeable entries if
1ffba6fe
LP
1122 * necessary and possible, merge entries we can
1123 * merge */
1124 if ((r = transaction_merge_jobs(m)) >= 0)
1125 break;
1126
9f04bd52
LP
1127 if (r != -EAGAIN) {
1128 log_debug("Requested transaction contains unmergable jobs: %s", strerror(-r));
1ffba6fe 1129 goto rollback;
9f04bd52 1130 }
1ffba6fe 1131
23a177ef 1132 /* Seventh step: an entry got dropped, let's garbage
1ffba6fe
LP
1133 * collect its dependencies. */
1134 transaction_collect_garbage(m);
1135
1136 /* Let's see if the resulting transaction still has
5cb5a6ff 1137 * unmergeable entries ... */
1ffba6fe
LP
1138 }
1139
23a177ef
LP
1140 /* Eights step: Drop redundant jobs again, if the merging now allows us to drop more. */
1141 transaction_drop_redundant(m);
1142
1143 /* Ninth step: check whether we can actually apply this */
e5b5ae50 1144 if (mode == JOB_FAIL)
c497c7a9 1145 if ((r = transaction_is_destructive(m)) < 0) {
9f04bd52 1146 log_debug("Requested transaction contradicts existing jobs: %s", strerror(-r));
e5b5ae50 1147 goto rollback;
9f04bd52 1148 }
e5b5ae50 1149
23a177ef 1150 /* Tenth step: apply changes */
c497c7a9 1151 if ((r = transaction_apply(m)) < 0) {
9f04bd52 1152 log_debug("Failed to apply transaction: %s", strerror(-r));
e5b5ae50 1153 goto rollback;
9f04bd52 1154 }
e5b5ae50
LP
1155
1156 assert(hashmap_isempty(m->transaction_jobs));
1157 assert(!m->transaction_anchor);
1158
1159 return 0;
11dd41ce 1160
e5b5ae50 1161rollback:
11dd41ce
LP
1162 transaction_abort(m);
1163 return r;
1164}
1165
9e2f7c11 1166static Job* transaction_add_one_job(Manager *m, JobType type, Unit *unit, bool override, bool *is_new) {
e5b5ae50 1167 Job *j, *f;
60918275
LP
1168 int r;
1169
1170 assert(m);
87f0e418 1171 assert(unit);
60918275 1172
e5b5ae50
LP
1173 /* Looks for an axisting prospective job and returns that. If
1174 * it doesn't exist it is created and added to the prospective
1175 * jobs list. */
60918275 1176
87f0e418 1177 f = hashmap_get(m->transaction_jobs, unit);
60918275 1178
034c6ed7 1179 LIST_FOREACH(transaction, j, f) {
87f0e418 1180 assert(j->unit == unit);
60918275 1181
e5b5ae50
LP
1182 if (j->type == type) {
1183 if (is_new)
1184 *is_new = false;
1185 return j;
1186 }
1187 }
60918275 1188
87f0e418
LP
1189 if (unit->meta.job && unit->meta.job->type == type)
1190 j = unit->meta.job;
1191 else if (!(j = job_new(m, type, unit)))
e5b5ae50 1192 return NULL;
60918275 1193
e5b5ae50
LP
1194 j->generation = 0;
1195 j->marker = NULL;
1196 j->matters_to_anchor = false;
9e2f7c11 1197 j->override = override;
60918275 1198
034c6ed7
LP
1199 LIST_PREPEND(Job, transaction, f, j);
1200
87f0e418 1201 if ((r = hashmap_replace(m->transaction_jobs, unit, f)) < 0) {
034c6ed7
LP
1202 job_free(j);
1203 return NULL;
1204 }
1205
e5b5ae50
LP
1206 if (is_new)
1207 *is_new = true;
60918275 1208
9e2f7c11 1209 log_debug("Added job %s/%s to transaction.", unit->meta.id, job_type_to_string(type));
23a177ef 1210
e5b5ae50
LP
1211 return j;
1212}
11dd41ce 1213
23a177ef 1214void manager_transaction_unlink_job(Manager *m, Job *j, bool delete_dependencies) {
e5b5ae50
LP
1215 assert(m);
1216 assert(j);
11dd41ce 1217
e5b5ae50
LP
1218 if (j->transaction_prev)
1219 j->transaction_prev->transaction_next = j->transaction_next;
1220 else if (j->transaction_next)
87f0e418 1221 hashmap_replace(m->transaction_jobs, j->unit, j->transaction_next);
e5b5ae50 1222 else
87f0e418 1223 hashmap_remove_value(m->transaction_jobs, j->unit, j);
e5b5ae50
LP
1224
1225 if (j->transaction_next)
1226 j->transaction_next->transaction_prev = j->transaction_prev;
1227
1228 j->transaction_prev = j->transaction_next = NULL;
1229
1230 while (j->subject_list)
1231 job_dependency_free(j->subject_list);
1e198baf
LP
1232
1233 while (j->object_list) {
1234 Job *other = j->object_list->matters ? j->object_list->subject : NULL;
1235
e5b5ae50 1236 job_dependency_free(j->object_list);
1e198baf 1237
23a177ef 1238 if (other && delete_dependencies) {
5cb5a6ff 1239 log_debug("Deleting job %s/%s as dependency of job %s/%s",
9e2f7c11
LP
1240 other->unit->meta.id, job_type_to_string(other->type),
1241 j->unit->meta.id, job_type_to_string(j->type));
23a177ef 1242 transaction_delete_job(m, other, delete_dependencies);
1e198baf
LP
1243 }
1244 }
e5b5ae50
LP
1245}
1246
9e2f7c11
LP
1247static int transaction_add_job_and_dependencies(
1248 Manager *m,
1249 JobType type,
1250 Unit *unit,
1251 Job *by,
1252 bool matters,
1253 bool override,
1254 Job **_ret) {
e5b5ae50 1255 Job *ret;
034c6ed7 1256 Iterator i;
87f0e418 1257 Unit *dep;
e5b5ae50
LP
1258 int r;
1259 bool is_new;
1260
1261 assert(m);
1262 assert(type < _JOB_TYPE_MAX);
87f0e418 1263 assert(unit);
e5b5ae50 1264
87f0e418 1265 if (unit->meta.load_state != UNIT_LOADED)
21b293e8
LP
1266 return -EINVAL;
1267
87f0e418 1268 if (!unit_job_is_applicable(unit, type))
cd2dbd7d
LP
1269 return -EBADR;
1270
e5b5ae50 1271 /* First add the job. */
9e2f7c11 1272 if (!(ret = transaction_add_one_job(m, type, unit, override, &is_new)))
e5b5ae50
LP
1273 return -ENOMEM;
1274
1275 /* Then, add a link to the job. */
1276 if (!job_dependency_new(by, ret, matters))
1277 return -ENOMEM;
1278
1279 if (is_new) {
1280 /* Finally, recursively add in all dependencies. */
1281 if (type == JOB_START || type == JOB_RELOAD_OR_START) {
87f0e418 1282 SET_FOREACH(dep, ret->unit->meta.dependencies[UNIT_REQUIRES], i)
9e2f7c11 1283 if ((r = transaction_add_job_and_dependencies(m, JOB_START, dep, ret, true, override, NULL)) < 0 && r != -EBADR)
e5b5ae50 1284 goto fail;
9e2f7c11
LP
1285
1286 SET_FOREACH(dep, ret->unit->meta.dependencies[UNIT_REQUIRES_OVERRIDABLE], i)
1287 if ((r = transaction_add_job_and_dependencies(m, JOB_START, dep, ret, !override, override, NULL)) < 0 && r != -EBADR)
1288 log_warning("Cannot add dependency job for unit %s, ignoring: %s", dep->meta.id, strerror(-r));
1289
87f0e418 1290 SET_FOREACH(dep, ret->unit->meta.dependencies[UNIT_WANTS], i)
9e2f7c11
LP
1291 if ((r = transaction_add_job_and_dependencies(m, JOB_START, dep, ret, false, false, NULL)) < 0)
1292 log_warning("Cannot add dependency job for unit %s, ignoring: %s", dep->meta.id, strerror(-r));
1293
87f0e418 1294 SET_FOREACH(dep, ret->unit->meta.dependencies[UNIT_REQUISITE], i)
9e2f7c11 1295 if ((r = transaction_add_job_and_dependencies(m, JOB_VERIFY_ACTIVE, dep, ret, true, override, NULL)) < 0 && r != -EBADR)
e5b5ae50 1296 goto fail;
9e2f7c11
LP
1297
1298 SET_FOREACH(dep, ret->unit->meta.dependencies[UNIT_REQUISITE_OVERRIDABLE], i)
1299 if ((r = transaction_add_job_and_dependencies(m, JOB_VERIFY_ACTIVE, dep, ret, !override, override, NULL)) < 0 && r != -EBADR)
1300 log_warning("Cannot add dependency job for unit %s, ignoring: %s", dep->meta.id, strerror(-r));
1301
87f0e418 1302 SET_FOREACH(dep, ret->unit->meta.dependencies[UNIT_CONFLICTS], i)
9e2f7c11 1303 if ((r = transaction_add_job_and_dependencies(m, JOB_STOP, dep, ret, true, override, NULL)) < 0 && r != -EBADR)
e5b5ae50
LP
1304 goto fail;
1305
1306 } else if (type == JOB_STOP || type == JOB_RESTART || type == JOB_TRY_RESTART) {
1307
87f0e418 1308 SET_FOREACH(dep, ret->unit->meta.dependencies[UNIT_REQUIRED_BY], i)
9e2f7c11 1309 if ((r = transaction_add_job_and_dependencies(m, type, dep, ret, true, override, NULL)) < 0 && r != -EBADR)
e5b5ae50
LP
1310 goto fail;
1311 }
1312
1313 /* JOB_VERIFY_STARTED, JOB_RELOAD require no dependency handling */
1314 }
60918275 1315
c0dafa48
LP
1316 if (_ret)
1317 *_ret = ret;
1318
60918275
LP
1319 return 0;
1320
1321fail:
e5b5ae50
LP
1322 return r;
1323}
1324
c497c7a9
LP
1325static int transaction_add_isolate_jobs(Manager *m) {
1326 Iterator i;
1327 Unit *u;
1328 char *k;
1329 int r;
1330
1331 assert(m);
1332
1333 HASHMAP_FOREACH_KEY(u, k, m->units, i) {
1334
1335 /* ignore aliases */
1336 if (u->meta.id != k)
1337 continue;
1338
1339 if (UNIT_VTABLE(u)->no_isolate)
1340 continue;
1341
1342 /* No need to stop inactive jobs */
1343 if (unit_active_state(u) == UNIT_INACTIVE)
1344 continue;
1345
1346 /* Is there already something listed for this? */
1347 if (hashmap_get(m->transaction_jobs, u))
1348 continue;
1349
1350 if ((r = transaction_add_job_and_dependencies(m, JOB_STOP, u, NULL, true, false, NULL)) < 0)
1351 log_warning("Cannot add isolate job for unit %s, ignoring: %s", u->meta.id, strerror(-r));
1352 }
1353
1354 return 0;
1355}
1356
9e2f7c11 1357int manager_add_job(Manager *m, JobType type, Unit *unit, JobMode mode, bool override, Job **_ret) {
e5b5ae50
LP
1358 int r;
1359 Job *ret;
1360
1361 assert(m);
1362 assert(type < _JOB_TYPE_MAX);
87f0e418 1363 assert(unit);
e5b5ae50 1364 assert(mode < _JOB_MODE_MAX);
60918275 1365
c497c7a9
LP
1366 if (mode == JOB_ISOLATE && type != JOB_START)
1367 return -EINVAL;
1368
9e2f7c11 1369 log_debug("Trying to enqueue job %s/%s", unit->meta.id, job_type_to_string(type));
9f04bd52 1370
9e2f7c11 1371 if ((r = transaction_add_job_and_dependencies(m, type, unit, NULL, true, override, &ret)) < 0) {
11dd41ce 1372 transaction_abort(m);
e5b5ae50
LP
1373 return r;
1374 }
11dd41ce 1375
c497c7a9
LP
1376 if (mode == JOB_ISOLATE)
1377 if ((r = transaction_add_isolate_jobs(m)) < 0) {
1378 transaction_abort(m);
1379 return r;
1380 }
1381
e5b5ae50
LP
1382 if ((r = transaction_activate(m, mode)) < 0)
1383 return r;
1384
9e2f7c11 1385 log_debug("Enqueued job %s/%s as %u", unit->meta.id, job_type_to_string(type), (unsigned) ret->id);
f50e0a01 1386
e5b5ae50
LP
1387 if (_ret)
1388 *_ret = ret;
60918275 1389
e5b5ae50
LP
1390 return 0;
1391}
60918275 1392
9e2f7c11 1393int manager_add_job_by_name(Manager *m, JobType type, const char *name, JobMode mode, bool override, Job **_ret) {
28247076
LP
1394 Unit *unit;
1395 int r;
1396
1397 assert(m);
1398 assert(type < _JOB_TYPE_MAX);
1399 assert(name);
1400 assert(mode < _JOB_MODE_MAX);
1401
9e2f7c11 1402 if ((r = manager_load_unit(m, name, NULL, &unit)) < 0)
28247076
LP
1403 return r;
1404
9e2f7c11 1405 return manager_add_job(m, type, unit, mode, override, _ret);
28247076
LP
1406}
1407
60918275
LP
1408Job *manager_get_job(Manager *m, uint32_t id) {
1409 assert(m);
1410
1411 return hashmap_get(m->jobs, UINT32_TO_PTR(id));
1412}
1413
87f0e418 1414Unit *manager_get_unit(Manager *m, const char *name) {
60918275
LP
1415 assert(m);
1416 assert(name);
1417
87f0e418 1418 return hashmap_get(m->units, name);
60918275
LP
1419}
1420
c1e1601e 1421unsigned manager_dispatch_load_queue(Manager *m) {
60918275 1422 Meta *meta;
c1e1601e 1423 unsigned n = 0;
60918275
LP
1424
1425 assert(m);
1426
223dabab
LP
1427 /* Make sure we are not run recursively */
1428 if (m->dispatching_load_queue)
c1e1601e 1429 return 0;
223dabab
LP
1430
1431 m->dispatching_load_queue = true;
1432
87f0e418 1433 /* Dispatches the load queue. Takes a unit from the queue and
60918275
LP
1434 * tries to load its data until the queue is empty */
1435
1436 while ((meta = m->load_queue)) {
034c6ed7
LP
1437 assert(meta->in_load_queue);
1438
87f0e418 1439 unit_load(UNIT(meta));
c1e1601e 1440 n++;
60918275
LP
1441 }
1442
223dabab 1443 m->dispatching_load_queue = false;
c1e1601e 1444 return n;
60918275
LP
1445}
1446
db06e3b6 1447int manager_load_unit_prepare(Manager *m, const char *name, const char *path, Unit **_ret) {
87f0e418 1448 Unit *ret;
60918275
LP
1449 int r;
1450
1451 assert(m);
9e2f7c11 1452 assert(name || path);
60918275 1453
db06e3b6
LP
1454 /* This will prepare the unit for loading, but not actually
1455 * load anything from disk. */
0301abf4 1456
9e2f7c11
LP
1457 if (path && !is_path(path))
1458 return -EINVAL;
1459
1460 if (!name)
1461 name = file_name_from_path(path);
1462
1463 if (!unit_name_is_valid(name))
1464 return -EINVAL;
60918275 1465
87f0e418 1466 if ((ret = manager_get_unit(m, name))) {
034c6ed7 1467 *_ret = ret;
413d6313 1468 return 1;
034c6ed7 1469 }
60918275 1470
87f0e418 1471 if (!(ret = unit_new(m)))
60918275
LP
1472 return -ENOMEM;
1473
9e2f7c11 1474 if (path)
6be1e7d5 1475 if (!(ret->meta.fragment_path = strdup(path))) {
0301abf4
LP
1476 unit_free(ret);
1477 return -ENOMEM;
1478 }
0301abf4 1479
87f0e418
LP
1480 if ((r = unit_add_name(ret, name)) < 0) {
1481 unit_free(ret);
1ffba6fe 1482 return r;
60918275
LP
1483 }
1484
87f0e418 1485 unit_add_to_load_queue(ret);
c1e1601e 1486 unit_add_to_dbus_queue(ret);
949061f0 1487 unit_add_to_gc_queue(ret);
c1e1601e 1488
db06e3b6
LP
1489 if (_ret)
1490 *_ret = ret;
1491
1492 return 0;
1493}
1494
1495int manager_load_unit(Manager *m, const char *name, const char *path, Unit **_ret) {
db06e3b6
LP
1496 int r;
1497
1498 assert(m);
1499
1500 /* This will load the service information files, but not actually
1501 * start any services or anything. */
1502
413d6313 1503 if ((r = manager_load_unit_prepare(m, name, path, _ret)) != 0)
db06e3b6
LP
1504 return r;
1505
f50e0a01 1506 manager_dispatch_load_queue(m);
60918275 1507
9e2f7c11 1508 if (_ret)
413d6313 1509 *_ret = unit_follow_merge(*_ret);
9e2f7c11 1510
60918275
LP
1511 return 0;
1512}
a66d02c3 1513
cea8e32e 1514void manager_dump_jobs(Manager *s, FILE *f, const char *prefix) {
034c6ed7 1515 Iterator i;
a66d02c3
LP
1516 Job *j;
1517
1518 assert(s);
1519 assert(f);
1520
034c6ed7 1521 HASHMAP_FOREACH(j, s->jobs, i)
cea8e32e 1522 job_dump(j, f, prefix);
a66d02c3
LP
1523}
1524
87f0e418 1525void manager_dump_units(Manager *s, FILE *f, const char *prefix) {
034c6ed7 1526 Iterator i;
87f0e418 1527 Unit *u;
11dd41ce 1528 const char *t;
a66d02c3
LP
1529
1530 assert(s);
1531 assert(f);
1532
87f0e418 1533 HASHMAP_FOREACH_KEY(u, t, s->units, i)
9e2f7c11 1534 if (u->meta.id == t)
87f0e418 1535 unit_dump(u, f, prefix);
a66d02c3 1536}
7fad411c
LP
1537
1538void manager_clear_jobs(Manager *m) {
1539 Job *j;
1540
1541 assert(m);
1542
1543 transaction_abort(m);
1544
1545 while ((j = hashmap_first(m->jobs)))
1546 job_free(j);
1547}
83c60c9f 1548
c1e1601e 1549unsigned manager_dispatch_run_queue(Manager *m) {
83c60c9f 1550 Job *j;
c1e1601e 1551 unsigned n = 0;
83c60c9f 1552
034c6ed7 1553 if (m->dispatching_run_queue)
c1e1601e 1554 return 0;
034c6ed7
LP
1555
1556 m->dispatching_run_queue = true;
9152c765 1557
034c6ed7 1558 while ((j = m->run_queue)) {
ac1135be 1559 assert(j->installed);
034c6ed7
LP
1560 assert(j->in_run_queue);
1561
1562 job_run_and_invalidate(j);
c1e1601e 1563 n++;
9152c765 1564 }
034c6ed7
LP
1565
1566 m->dispatching_run_queue = false;
c1e1601e
LP
1567 return n;
1568}
1569
1570unsigned manager_dispatch_dbus_queue(Manager *m) {
1571 Job *j;
1572 Meta *meta;
1573 unsigned n = 0;
1574
1575 assert(m);
1576
1577 if (m->dispatching_dbus_queue)
1578 return 0;
1579
1580 m->dispatching_dbus_queue = true;
1581
1582 while ((meta = m->dbus_unit_queue)) {
23a177ef 1583 assert(meta->in_dbus_queue);
c1e1601e 1584
23a177ef 1585 bus_unit_send_change_signal(UNIT(meta));
c1e1601e
LP
1586 n++;
1587 }
1588
1589 while ((j = m->dbus_job_queue)) {
1590 assert(j->in_dbus_queue);
1591
1592 bus_job_send_change_signal(j);
1593 n++;
1594 }
1595
1596 m->dispatching_dbus_queue = false;
1597 return n;
9152c765
LP
1598}
1599
8c47c732
LP
1600static int manager_process_notify_fd(Manager *m) {
1601 ssize_t n;
1602
1603 assert(m);
1604
1605 for (;;) {
1606 char buf[4096];
1607 struct msghdr msghdr;
1608 struct iovec iovec;
1609 struct ucred *ucred;
1610 union {
1611 struct cmsghdr cmsghdr;
1612 uint8_t buf[CMSG_SPACE(sizeof(struct ucred))];
1613 } control;
1614 Unit *u;
1615 char **tags;
1616
1617 zero(iovec);
1618 iovec.iov_base = buf;
1619 iovec.iov_len = sizeof(buf)-1;
1620
1621 zero(control);
1622 zero(msghdr);
1623 msghdr.msg_iov = &iovec;
1624 msghdr.msg_iovlen = 1;
1625 msghdr.msg_control = &control;
1626 msghdr.msg_controllen = sizeof(control);
1627
1628 if ((n = recvmsg(m->notify_watch.fd, &msghdr, MSG_DONTWAIT)) <= 0) {
1629 if (n >= 0)
1630 return -EIO;
1631
1632 if (errno == EAGAIN)
1633 break;
1634
1635 return -errno;
1636 }
1637
1638 if (msghdr.msg_controllen < CMSG_LEN(sizeof(struct ucred)) ||
1639 control.cmsghdr.cmsg_level != SOL_SOCKET ||
1640 control.cmsghdr.cmsg_type != SCM_CREDENTIALS ||
1641 control.cmsghdr.cmsg_len != CMSG_LEN(sizeof(struct ucred))) {
1642 log_warning("Received notify message without credentials. Ignoring.");
1643 continue;
1644 }
1645
1646 ucred = (struct ucred*) CMSG_DATA(&control.cmsghdr);
1647
1648 if (!(u = hashmap_get(m->watch_pids, UINT32_TO_PTR(ucred->pid))))
1649 if (!(u = cgroup_unit_by_pid(m, ucred->pid))) {
1650 log_warning("Cannot find unit for notify message of PID %lu.", (unsigned long) ucred->pid);
1651 continue;
1652 }
1653
1654 char_array_0(buf);
1655 if (!(tags = strv_split(buf, "\n\r")))
1656 return -ENOMEM;
1657
1658 log_debug("Got notification message for unit %s", u->meta.id);
1659
1660 if (UNIT_VTABLE(u)->notify_message)
1661 UNIT_VTABLE(u)->notify_message(u, tags);
1662
1663 strv_free(tags);
1664 }
1665
1666 return 0;
1667}
1668
034c6ed7 1669static int manager_dispatch_sigchld(Manager *m) {
9152c765
LP
1670 assert(m);
1671
1672 for (;;) {
1673 siginfo_t si;
87f0e418 1674 Unit *u;
8c47c732 1675 int r;
9152c765
LP
1676
1677 zero(si);
4112df16
LP
1678
1679 /* First we call waitd() for a PID and do not reap the
1680 * zombie. That way we can still access /proc/$PID for
1681 * it while it is a zombie. */
1682 if (waitid(P_ALL, 0, &si, WEXITED|WNOHANG|WNOWAIT) < 0) {
acbb0225
LP
1683
1684 if (errno == ECHILD)
1685 break;
1686
4112df16
LP
1687 if (errno == EINTR)
1688 continue;
1689
9152c765 1690 return -errno;
acbb0225 1691 }
9152c765 1692
4112df16 1693 if (si.si_pid <= 0)
9152c765
LP
1694 break;
1695
15d5d9d9 1696 if (si.si_code == CLD_EXITED || si.si_code == CLD_KILLED || si.si_code == CLD_DUMPED) {
4112df16
LP
1697 char *name = NULL;
1698
1699 get_process_name(si.si_pid, &name);
1700 log_debug("Got SIGCHLD for process %llu (%s)", (unsigned long long) si.si_pid, strna(name));
1701 free(name);
1702 }
1703
8c47c732
LP
1704 /* Let's flush any message the dying child might still
1705 * have queued for us. This ensures that the process
1706 * still exists in /proc so that we can figure out
1707 * which cgroup and hence unit it belongs to. */
1708 if ((r = manager_process_notify_fd(m)) < 0)
1709 return r;
1710
1711 /* And now figure out the unit this belongs to */
1712 if (!(u = hashmap_get(m->watch_pids, UINT32_TO_PTR(si.si_pid))))
1713 u = cgroup_unit_by_pid(m, si.si_pid);
1714
4112df16
LP
1715 /* And now, we actually reap the zombie. */
1716 if (waitid(P_PID, si.si_pid, &si, WEXITED) < 0) {
1717 if (errno == EINTR)
1718 continue;
1719
1720 return -errno;
1721 }
1722
034c6ed7
LP
1723 if (si.si_code != CLD_EXITED && si.si_code != CLD_KILLED && si.si_code != CLD_DUMPED)
1724 continue;
1725
4112df16
LP
1726 log_debug("Child %llu died (code=%s, status=%i/%s)",
1727 (long long unsigned) si.si_pid,
1728 sigchld_code_to_string(si.si_code),
1729 si.si_status,
1730 strna(si.si_code == CLD_EXITED ? exit_status_to_string(si.si_status) : strsignal(si.si_status)));
acbb0225 1731
8c47c732 1732 if (!u)
9152c765
LP
1733 continue;
1734
9e2f7c11 1735 log_debug("Child %llu belongs to %s", (long long unsigned) si.si_pid, u->meta.id);
6c1a0478 1736
8c47c732 1737 hashmap_remove(m->watch_pids, UINT32_TO_PTR(si.si_pid));
87f0e418 1738 UNIT_VTABLE(u)->sigchld_event(u, si.si_pid, si.si_code, si.si_status);
9152c765
LP
1739 }
1740
1741 return 0;
1742}
1743
7d793605 1744static int manager_start_target(Manager *m, const char *name, JobMode mode) {
28247076
LP
1745 int r;
1746
7d793605 1747 if ((r = manager_add_job_by_name(m, JOB_START, name, mode, true, NULL)) < 0)
28247076 1748 log_error("Failed to enqueue %s job: %s", name, strerror(-r));
a1b256b0
LP
1749
1750 return r;
28247076
LP
1751}
1752
a16e1123 1753static int manager_process_signal_fd(Manager *m) {
9152c765
LP
1754 ssize_t n;
1755 struct signalfd_siginfo sfsi;
1756 bool sigchld = false;
1757
1758 assert(m);
1759
1760 for (;;) {
acbb0225 1761 if ((n = read(m->signal_watch.fd, &sfsi, sizeof(sfsi))) != sizeof(sfsi)) {
9152c765
LP
1762
1763 if (n >= 0)
1764 return -EIO;
1765
1766 if (errno == EAGAIN)
acbb0225 1767 break;
9152c765
LP
1768
1769 return -errno;
1770 }
1771
b9cd2ec1
LP
1772 switch (sfsi.ssi_signo) {
1773
4112df16 1774 case SIGCHLD:
9152c765 1775 sigchld = true;
b9cd2ec1
LP
1776 break;
1777
6632c602 1778 case SIGTERM:
a1b256b0 1779 if (m->running_as == MANAGER_INIT) {
db06e3b6
LP
1780 /* This is for compatibility with the
1781 * original sysvinit */
e11dc4a2 1782 m->exit_code = MANAGER_REEXECUTE;
a1b256b0
LP
1783 break;
1784 }
84e9af1e 1785
a1b256b0 1786 /* Fall through */
e11dc4a2
LP
1787
1788 case SIGINT:
28247076 1789 if (m->running_as == MANAGER_INIT) {
7d793605 1790 manager_start_target(m, SPECIAL_CTRL_ALT_DEL_TARGET, JOB_REPLACE);
84e9af1e
LP
1791 break;
1792 }
1793
a1b256b0 1794 /* Run the exit target if there is one, if not, just exit. */
7d793605 1795 if (manager_start_target(m, SPECIAL_EXIT_SERVICE, JOB_REPLACE) < 0) {
a1b256b0
LP
1796 m->exit_code = MANAGER_EXIT;
1797 return 0;
1798 }
1799
1800 break;
84e9af1e 1801
28247076 1802 case SIGWINCH:
28247076 1803 if (m->running_as == MANAGER_INIT)
7d793605 1804 manager_start_target(m, SPECIAL_KBREQUEST_TARGET, JOB_REPLACE);
84e9af1e 1805
28247076
LP
1806 /* This is a nop on non-init */
1807 break;
84e9af1e 1808
28247076
LP
1809 case SIGPWR:
1810 if (m->running_as == MANAGER_INIT)
7d793605 1811 manager_start_target(m, SPECIAL_SIGPWR_TARGET, JOB_REPLACE);
84e9af1e 1812
28247076 1813 /* This is a nop on non-init */
84e9af1e 1814 break;
6632c602 1815
1005d14f 1816 case SIGUSR1: {
57ee42ce
LP
1817 Unit *u;
1818
1819 u = manager_get_unit(m, SPECIAL_DBUS_SERVICE);
1820
1821 if (!u || UNIT_IS_ACTIVE_OR_RELOADING(unit_active_state(u))) {
1822 log_info("Trying to reconnect to bus...");
1823 bus_init_system(m);
1824 bus_init_api(m);
1825 }
1826
1827 if (!u || !UNIT_IS_ACTIVE_OR_ACTIVATING(unit_active_state(u))) {
1828 log_info("Loading D-Bus service...");
7d793605 1829 manager_start_target(m, SPECIAL_DBUS_SERVICE, JOB_REPLACE);
57ee42ce
LP
1830 }
1831
1832 break;
1833 }
1834
2149e37c
LP
1835 case SIGUSR2: {
1836 FILE *f;
1837 char *dump = NULL;
1838 size_t size;
1839
1840 if (!(f = open_memstream(&dump, &size))) {
1841 log_warning("Failed to allocate memory stream.");
1842 break;
1843 }
1844
1845 manager_dump_units(m, f, "\t");
1846 manager_dump_jobs(m, f, "\t");
1847
1848 if (ferror(f)) {
1849 fclose(f);
1850 free(dump);
1851 log_warning("Failed to write status stream");
1852 break;
1853 }
1854
1855 fclose(f);
1856 log_dump(LOG_INFO, dump);
1857 free(dump);
1858
1005d14f 1859 break;
2149e37c 1860 }
1005d14f 1861
a16e1123
LP
1862 case SIGHUP:
1863 m->exit_code = MANAGER_RELOAD;
1864 break;
1865
7d793605
LP
1866 default: {
1867 static const char * const table[] = {
1868 [0] = SPECIAL_DEFAULT_TARGET,
1869 [1] = SPECIAL_RESCUE_TARGET,
1870 [2] = SPECIAL_EMERGENCY_SERVICE,
1871 [3] = SPECIAL_HALT_TARGET,
1872 [4] = SPECIAL_POWEROFF_TARGET,
1873 [5] = SPECIAL_REBOOT_TARGET
1874 };
1875
1876 if ((int) sfsi.ssi_signo >= SIGRTMIN+0 &&
1877 (int) sfsi.ssi_signo < SIGRTMIN+(int) ELEMENTSOF(table)) {
1878 manager_start_target(m, table[sfsi.ssi_signo - SIGRTMIN],
1879 sfsi.ssi_signo == 2 ? JOB_ISOLATE : JOB_REPLACE);
1880 break;
1881 }
1882
6632c602 1883 log_info("Got unhandled signal <%s>.", strsignal(sfsi.ssi_signo));
b9cd2ec1 1884 }
7d793605 1885 }
9152c765
LP
1886 }
1887
1888 if (sigchld)
034c6ed7
LP
1889 return manager_dispatch_sigchld(m);
1890
1891 return 0;
1892}
1893
a16e1123 1894static int process_event(Manager *m, struct epoll_event *ev) {
034c6ed7 1895 int r;
acbb0225 1896 Watch *w;
034c6ed7
LP
1897
1898 assert(m);
1899 assert(ev);
1900
acbb0225 1901 assert(w = ev->data.ptr);
034c6ed7 1902
acbb0225 1903 switch (w->type) {
034c6ed7 1904
ef734fd6 1905 case WATCH_SIGNAL:
034c6ed7 1906
acbb0225 1907 /* An incoming signal? */
f94ea366 1908 if (ev->events != EPOLLIN)
acbb0225 1909 return -EINVAL;
034c6ed7 1910
a16e1123 1911 if ((r = manager_process_signal_fd(m)) < 0)
acbb0225 1912 return r;
034c6ed7 1913
acbb0225 1914 break;
034c6ed7 1915
8c47c732
LP
1916 case WATCH_NOTIFY:
1917
1918 /* An incoming daemon notification event? */
1919 if (ev->events != EPOLLIN)
1920 return -EINVAL;
1921
1922 if ((r = manager_process_notify_fd(m)) < 0)
1923 return r;
1924
1925 break;
1926
acbb0225 1927 case WATCH_FD:
034c6ed7 1928
acbb0225 1929 /* Some fd event, to be dispatched to the units */
ea430986 1930 UNIT_VTABLE(w->data.unit)->fd_event(w->data.unit, w->fd, ev->events, w);
acbb0225 1931 break;
034c6ed7 1932
acbb0225
LP
1933 case WATCH_TIMER: {
1934 uint64_t v;
1935 ssize_t k;
034c6ed7 1936
acbb0225 1937 /* Some timer event, to be dispatched to the units */
be888ebb 1938 if ((k = read(w->fd, &v, sizeof(v))) != sizeof(v)) {
034c6ed7 1939
acbb0225
LP
1940 if (k < 0 && (errno == EINTR || errno == EAGAIN))
1941 break;
034c6ed7 1942
acbb0225 1943 return k < 0 ? -errno : -EIO;
034c6ed7
LP
1944 }
1945
ea430986 1946 UNIT_VTABLE(w->data.unit)->timer_event(w->data.unit, v, w);
acbb0225
LP
1947 break;
1948 }
1949
ef734fd6
LP
1950 case WATCH_MOUNT:
1951 /* Some mount table change, intended for the mount subsystem */
1952 mount_fd_event(m, ev->events);
1953 break;
1954
f94ea366
LP
1955 case WATCH_UDEV:
1956 /* Some notification from udev, intended for the device subsystem */
1957 device_fd_event(m, ev->events);
1958 break;
1959
ea430986
LP
1960 case WATCH_DBUS_WATCH:
1961 bus_watch_event(m, w, ev->events);
1962 break;
1963
1964 case WATCH_DBUS_TIMEOUT:
1965 bus_timeout_event(m, w, ev->events);
1966 break;
1967
acbb0225
LP
1968 default:
1969 assert_not_reached("Unknown epoll event type.");
034c6ed7 1970 }
9152c765
LP
1971
1972 return 0;
1973}
1974
1975int manager_loop(Manager *m) {
1976 int r;
9152c765 1977
ea430986
LP
1978 RATELIMIT_DEFINE(rl, 1*USEC_PER_SEC, 1000);
1979
9152c765 1980 assert(m);
a16e1123 1981 m->exit_code = MANAGER_RUNNING;
9152c765 1982
a4312405
LP
1983 /* There might still be some zombies hanging around from
1984 * before we were exec()'ed. Leat's reap them */
1985 if ((r = manager_dispatch_sigchld(m)) < 0)
1986 return r;
1987
a16e1123 1988 while (m->exit_code == MANAGER_RUNNING) {
957ca890
LP
1989 struct epoll_event event;
1990 int n;
9152c765 1991
ea430986
LP
1992 if (!ratelimit_test(&rl)) {
1993 /* Yay, something is going seriously wrong, pause a little */
1994 log_warning("Looping too fast. Throttling execution a little.");
1995 sleep(1);
1996 }
1997
37a8e683 1998 if (manager_dispatch_load_queue(m) > 0)
23a177ef
LP
1999 continue;
2000
37a8e683 2001 if (manager_dispatch_run_queue(m) > 0)
701cc384
LP
2002 continue;
2003
37a8e683 2004 if (bus_dispatch(m) > 0)
c1e1601e 2005 continue;
034c6ed7 2006
37a8e683 2007 if (manager_dispatch_cleanup_queue(m) > 0)
c1e1601e
LP
2008 continue;
2009
37a8e683 2010 if (manager_dispatch_gc_queue(m) > 0)
c1e1601e
LP
2011 continue;
2012
2013 if (manager_dispatch_dbus_queue(m) > 0)
ea430986 2014 continue;
ea430986 2015
957ca890 2016 if ((n = epoll_wait(m->epoll_fd, &event, 1, -1)) < 0) {
9152c765 2017
6089f4a9 2018 if (errno == EINTR)
9152c765
LP
2019 continue;
2020
2021 return -errno;
2022 }
2023
957ca890 2024 assert(n == 1);
b9cd2ec1 2025
a16e1123 2026 if ((r = process_event(m, &event)) < 0)
957ca890 2027 return r;
a16e1123 2028 }
957ca890 2029
a16e1123 2030 return m->exit_code;
83c60c9f 2031}
ea430986
LP
2032
2033int manager_get_unit_from_dbus_path(Manager *m, const char *s, Unit **_u) {
2034 char *n;
2035 Unit *u;
2036
2037 assert(m);
2038 assert(s);
2039 assert(_u);
2040
2041 if (!startswith(s, "/org/freedesktop/systemd1/unit/"))
2042 return -EINVAL;
2043
2044 if (!(n = bus_path_unescape(s+31)))
2045 return -ENOMEM;
2046
2047 u = manager_get_unit(m, n);
2048 free(n);
2049
2050 if (!u)
2051 return -ENOENT;
2052
2053 *_u = u;
2054
2055 return 0;
2056}
86fbf370
LP
2057
2058int manager_get_job_from_dbus_path(Manager *m, const char *s, Job **_j) {
2059 Job *j;
2060 unsigned id;
2061 int r;
2062
2063 assert(m);
2064 assert(s);
2065 assert(_j);
2066
2067 if (!startswith(s, "/org/freedesktop/systemd1/job/"))
2068 return -EINVAL;
2069
2070 if ((r = safe_atou(s + 30, &id)) < 0)
2071 return r;
2072
2073 if (!(j = manager_get_job(m, id)))
2074 return -ENOENT;
2075
2076 *_j = j;
2077
2078 return 0;
2079}
dfcd764e 2080
e537352b
LP
2081static bool manager_utmp_good(Manager *m) {
2082 int r;
2083
2084 assert(m);
2085
2086 if ((r = mount_path_is_mounted(m, _PATH_UTMPX)) <= 0) {
2087
2088 if (r < 0)
2089 log_warning("Failed to determine whether " _PATH_UTMPX " is mounted: %s", strerror(-r));
2090
2091 return false;
2092 }
2093
2094 return true;
2095}
2096
2097void manager_write_utmp_reboot(Manager *m) {
2098 int r;
2099
2100 assert(m);
2101
2102 if (m->utmp_reboot_written)
2103 return;
2104
2105 if (m->running_as != MANAGER_INIT)
2106 return;
2107
2108 if (!manager_utmp_good(m))
2109 return;
2110
871d7de4 2111 if ((r = utmp_put_reboot(m->startup_timestamp.realtime)) < 0) {
e537352b
LP
2112
2113 if (r != -ENOENT && r != -EROFS)
2114 log_warning("Failed to write utmp/wtmp: %s", strerror(-r));
2115
2116 return;
2117 }
2118
2119 m->utmp_reboot_written = true;
2120}
2121
2122void manager_write_utmp_runlevel(Manager *m, Unit *u) {
2123 int runlevel, r;
2124
2125 assert(m);
2126 assert(u);
2127
2128 if (u->meta.type != UNIT_TARGET)
2129 return;
2130
2131 if (m->running_as != MANAGER_INIT)
2132 return;
2133
2134 if (!manager_utmp_good(m))
2135 return;
2136
2137 if ((runlevel = target_get_runlevel(TARGET(u))) <= 0)
2138 return;
2139
2140 if ((r = utmp_put_runlevel(0, runlevel, 0)) < 0) {
2141
2142 if (r != -ENOENT && r != -EROFS)
2143 log_warning("Failed to write utmp/wtmp: %s", strerror(-r));
2144 }
2145}
2146
05e343b7
LP
2147void manager_dispatch_bus_name_owner_changed(
2148 Manager *m,
2149 const char *name,
2150 const char* old_owner,
2151 const char *new_owner) {
2152
2153 Unit *u;
2154
2155 assert(m);
2156 assert(name);
2157
2158 if (!(u = hashmap_get(m->watch_bus, name)))
2159 return;
2160
2161 UNIT_VTABLE(u)->bus_name_owner_change(u, name, old_owner, new_owner);
2162}
2163
2164void manager_dispatch_bus_query_pid_done(
2165 Manager *m,
2166 const char *name,
2167 pid_t pid) {
2168
2169 Unit *u;
2170
2171 assert(m);
2172 assert(name);
2173 assert(pid >= 1);
2174
2175 if (!(u = hashmap_get(m->watch_bus, name)))
2176 return;
2177
2178 UNIT_VTABLE(u)->bus_query_pid_done(u, name, pid);
2179}
2180
a16e1123
LP
2181int manager_open_serialization(FILE **_f) {
2182 char *path;
2183 mode_t saved_umask;
2184 int fd;
2185 FILE *f;
2186
2187 assert(_f);
2188
2189 if (asprintf(&path, "/dev/shm/systemd-%u.dump-XXXXXX", (unsigned) getpid()) < 0)
2190 return -ENOMEM;
2191
2192 saved_umask = umask(0077);
2193 fd = mkostemp(path, O_RDWR|O_CLOEXEC);
2194 umask(saved_umask);
2195
2196 if (fd < 0) {
2197 free(path);
2198 return -errno;
2199 }
2200
2201 unlink(path);
2202
2203 log_debug("Serializing state to %s", path);
2204 free(path);
2205
2206 if (!(f = fdopen(fd, "w+")) < 0)
2207 return -errno;
2208
2209 *_f = f;
2210
2211 return 0;
2212}
2213
2214int manager_serialize(Manager *m, FILE *f, FDSet *fds) {
2215 Iterator i;
2216 Unit *u;
2217 const char *t;
2218 int r;
2219
2220 assert(m);
2221 assert(f);
2222 assert(fds);
2223
2224 HASHMAP_FOREACH_KEY(u, t, m->units, i) {
2225 if (u->meta.id != t)
2226 continue;
2227
2228 if (!unit_can_serialize(u))
2229 continue;
2230
2231 /* Start marker */
2232 fputs(u->meta.id, f);
2233 fputc('\n', f);
2234
2235 if ((r = unit_serialize(u, f, fds)) < 0)
2236 return r;
2237 }
2238
2239 if (ferror(f))
2240 return -EIO;
2241
2242 return 0;
2243}
2244
2245int manager_deserialize(Manager *m, FILE *f, FDSet *fds) {
2246 int r = 0;
2247
2248 assert(m);
2249 assert(f);
2250
2251 log_debug("Deserializing state...");
2252
2253 for (;;) {
2254 Unit *u;
2255 char name[UNIT_NAME_MAX+2];
2256
2257 /* Start marker */
2258 if (!fgets(name, sizeof(name), f)) {
2259 if (feof(f))
2260 break;
2261
2262 return -errno;
2263 }
2264
2265 char_array_0(name);
2266
2267 if ((r = manager_load_unit(m, strstrip(name), NULL, &u)) < 0)
2268 return r;
2269
2270 if ((r = unit_deserialize(u, f, fds)) < 0)
2271 return r;
2272 }
2273
2274 if (ferror(f))
2275 return -EIO;
2276
2277 return 0;
2278}
2279
2280int manager_reload(Manager *m) {
2281 int r, q;
2282 FILE *f;
2283 FDSet *fds;
2284
2285 assert(m);
2286
2287 if ((r = manager_open_serialization(&f)) < 0)
2288 return r;
2289
2290 if (!(fds = fdset_new())) {
2291 r = -ENOMEM;
2292 goto finish;
2293 }
2294
2295 if ((r = manager_serialize(m, f, fds)) < 0)
2296 goto finish;
2297
2298 if (fseeko(f, 0, SEEK_SET) < 0) {
2299 r = -errno;
2300 goto finish;
2301 }
2302
2303 /* From here on there is no way back. */
2304 manager_clear_jobs_and_units(m);
2305
2ded0c04 2306 /* Find new unit paths */
84e3543e
LP
2307 lookup_paths_free(&m->lookup_paths);
2308 if ((q = lookup_paths_init(&m->lookup_paths, m->running_as)) < 0)
2ded0c04
LP
2309 r = q;
2310
a16e1123
LP
2311 /* First, enumerate what we can from all config files */
2312 if ((q = manager_enumerate(m)) < 0)
2313 r = q;
2314
2315 /* Second, deserialize our stored data */
2316 if ((q = manager_deserialize(m, f, fds)) < 0)
2317 r = q;
2318
2319 fclose(f);
2320 f = NULL;
2321
2322 /* Third, fire things up! */
2323 if ((q = manager_coldplug(m)) < 0)
2324 r = q;
2325
2326finish:
2327 if (f)
2328 fclose(f);
2329
2330 if (fds)
2331 fdset_free(fds);
2332
2333 return r;
2334}
2335
dfcd764e
LP
2336static const char* const manager_running_as_table[_MANAGER_RUNNING_AS_MAX] = {
2337 [MANAGER_INIT] = "init",
2338 [MANAGER_SYSTEM] = "system",
036643a2 2339 [MANAGER_SESSION] = "session"
dfcd764e
LP
2340};
2341
2342DEFINE_STRING_TABLE_LOOKUP(manager_running_as, ManagerRunningAs);