]> git.ipfire.org Git - thirdparty/systemd.git/blame - unit.c
systemctl: log whenever a unit/job changes
[thirdparty/systemd.git] / unit.c
CommitLineData
87f0e418
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
87f0e418
LP
22#include <assert.h>
23#include <errno.h>
24#include <string.h>
25#include <sys/epoll.h>
26#include <sys/timerfd.h>
27#include <sys/poll.h>
0301abf4
LP
28#include <stdlib.h>
29#include <unistd.h>
87f0e418
LP
30
31#include "set.h"
32#include "unit.h"
33#include "macro.h"
34#include "strv.h"
35#include "load-fragment.h"
36#include "load-dropin.h"
37#include "log.h"
9e2f7c11
LP
38#include "unit-name.h"
39#include "specifier.h"
4139c1b2 40#include "dbus-unit.h"
87f0e418
LP
41
42const UnitVTable * const unit_vtable[_UNIT_TYPE_MAX] = {
43 [UNIT_SERVICE] = &service_vtable,
44 [UNIT_TIMER] = &timer_vtable,
45 [UNIT_SOCKET] = &socket_vtable,
46 [UNIT_TARGET] = &target_vtable,
47 [UNIT_DEVICE] = &device_vtable,
48 [UNIT_MOUNT] = &mount_vtable,
49 [UNIT_AUTOMOUNT] = &automount_vtable,
07b0b134
ML
50 [UNIT_SNAPSHOT] = &snapshot_vtable,
51 [UNIT_SWAP] = &swap_vtable
87f0e418
LP
52};
53
87f0e418
LP
54Unit *unit_new(Manager *m) {
55 Unit *u;
56
57 assert(m);
58
59 if (!(u = new0(Unit, 1)))
60 return NULL;
61
62 if (!(u->meta.names = set_new(string_hash_func, string_compare_func))) {
63 free(u);
64 return NULL;
65 }
66
67 u->meta.manager = m;
68 u->meta.type = _UNIT_TYPE_INVALID;
69
70 return u;
71}
72
f278026d
LP
73bool unit_has_name(Unit *u, const char *name) {
74 assert(u);
75 assert(name);
76
77 return !!set_get(u->meta.names, (char*) name);
78}
79
87f0e418
LP
80int unit_add_name(Unit *u, const char *text) {
81 UnitType t;
9e2f7c11 82 char *s = NULL, *i = NULL;
87f0e418
LP
83 int r;
84
85 assert(u);
86 assert(text);
87
9e2f7c11
LP
88 if (unit_name_is_template(text)) {
89 if (!u->meta.instance)
90 return -EINVAL;
87f0e418 91
9e2f7c11
LP
92 s = unit_name_replace_instance(text, u->meta.instance);
93 } else
94 s = strdup(text);
87f0e418 95
9e2f7c11
LP
96 if (!s)
97 return -ENOMEM;
87f0e418 98
9e2f7c11
LP
99 if (!unit_name_is_valid(s)) {
100 r = -EINVAL;
101 goto fail;
102 }
e537352b 103
9e2f7c11 104 assert_se((t = unit_name_to_type(s)) >= 0);
87f0e418 105
9e2f7c11
LP
106 if (u->meta.type != _UNIT_TYPE_INVALID && t != u->meta.type) {
107 r = -EINVAL;
108 goto fail;
109 }
87f0e418 110
9e2f7c11
LP
111 if ((r = unit_name_to_instance(s, &i)) < 0)
112 goto fail;
87f0e418 113
9e2f7c11
LP
114 if (i && unit_vtable[t]->no_instances)
115 goto fail;
116
117 if (u->meta.type != _UNIT_TYPE_INVALID && !streq_ptr(u->meta.instance, i)) {
118 r = -EINVAL;
119 goto fail;
120 }
121
122 if (unit_vtable[t]->no_alias &&
123 !set_isempty(u->meta.names) &&
124 !set_get(u->meta.names, s)) {
125 r = -EEXIST;
126 goto fail;
127 }
128
4f0f902f
LP
129 if (hashmap_size(u->meta.manager->units) >= MANAGER_MAX_NAMES) {
130 r = -E2BIG;
131 goto fail;
132 }
133
9e2f7c11
LP
134 if ((r = set_put(u->meta.names, s)) < 0) {
135 if (r == -EEXIST)
136 r = 0;
137 goto fail;
87f0e418
LP
138 }
139
140 if ((r = hashmap_put(u->meta.manager->units, s, u)) < 0) {
141 set_remove(u->meta.names, s);
9e2f7c11 142 goto fail;
87f0e418
LP
143 }
144
e537352b 145 if (u->meta.type == _UNIT_TYPE_INVALID) {
ef734fd6 146
e537352b 147 u->meta.type = t;
9e2f7c11
LP
148 u->meta.id = s;
149 u->meta.instance = i;
150
151 LIST_PREPEND(Meta, units_per_type, u->meta.manager->units_per_type[t], &u->meta);
e537352b
LP
152
153 if (UNIT_VTABLE(u)->init)
154 UNIT_VTABLE(u)->init(u);
9e2f7c11
LP
155 } else
156 free(i);
87f0e418 157
c1e1601e 158 unit_add_to_dbus_queue(u);
87f0e418 159 return 0;
9e2f7c11
LP
160
161fail:
162 free(s);
163 free(i);
164
165 return r;
87f0e418
LP
166}
167
0ae97ec1 168int unit_choose_id(Unit *u, const char *name) {
9e2f7c11 169 char *s, *t = NULL;
0ae97ec1
LP
170
171 assert(u);
172 assert(name);
173
9e2f7c11
LP
174 if (unit_name_is_template(name)) {
175
176 if (!u->meta.instance)
177 return -EINVAL;
178
179 if (!(t = unit_name_replace_instance(name, u->meta.instance)))
180 return -ENOMEM;
181
182 name = t;
183 }
184
0ae97ec1 185 /* Selects one of the names of this unit as the id */
9e2f7c11
LP
186 s = set_get(u->meta.names, (char*) name);
187 free(t);
0ae97ec1 188
9e2f7c11 189 if (!s)
0ae97ec1
LP
190 return -ENOENT;
191
192 u->meta.id = s;
c1e1601e 193 unit_add_to_dbus_queue(u);
9e2f7c11 194
0ae97ec1
LP
195 return 0;
196}
197
f50e0a01
LP
198int unit_set_description(Unit *u, const char *description) {
199 char *s;
200
201 assert(u);
202
203 if (!(s = strdup(description)))
204 return -ENOMEM;
205
206 free(u->meta.description);
207 u->meta.description = s;
c1e1601e
LP
208
209 unit_add_to_dbus_queue(u);
f50e0a01
LP
210 return 0;
211}
212
701cc384
LP
213bool unit_check_gc(Unit *u) {
214 assert(u);
215
216 if (UNIT_VTABLE(u)->no_gc)
217 return true;
218
219 if (u->meta.job)
220 return true;
221
222 if (unit_active_state(u) != UNIT_INACTIVE)
223 return true;
224
225 if (UNIT_VTABLE(u)->check_gc)
226 if (UNIT_VTABLE(u)->check_gc(u))
227 return true;
228
229 return false;
230}
231
87f0e418
LP
232void unit_add_to_load_queue(Unit *u) {
233 assert(u);
819e213f 234 assert(u->meta.type != _UNIT_TYPE_INVALID);
87f0e418
LP
235
236 if (u->meta.load_state != UNIT_STUB || u->meta.in_load_queue)
237 return;
238
239 LIST_PREPEND(Meta, load_queue, u->meta.manager->load_queue, &u->meta);
240 u->meta.in_load_queue = true;
241}
242
23a177ef
LP
243void unit_add_to_cleanup_queue(Unit *u) {
244 assert(u);
245
246 if (u->meta.in_cleanup_queue)
247 return;
248
249 LIST_PREPEND(Meta, cleanup_queue, u->meta.manager->cleanup_queue, &u->meta);
250 u->meta.in_cleanup_queue = true;
251}
252
701cc384
LP
253void unit_add_to_gc_queue(Unit *u) {
254 assert(u);
255
256 if (u->meta.in_gc_queue || u->meta.in_cleanup_queue)
257 return;
258
259 if (unit_check_gc(u))
260 return;
261
262 LIST_PREPEND(Meta, gc_queue, u->meta.manager->gc_queue, &u->meta);
263 u->meta.in_gc_queue = true;
264
265 u->meta.manager->n_in_gc_queue ++;
266
267 if (u->meta.manager->gc_queue_timestamp <= 0)
268 u->meta.manager->gc_queue_timestamp = now(CLOCK_MONOTONIC);
269}
270
c1e1601e
LP
271void unit_add_to_dbus_queue(Unit *u) {
272 assert(u);
819e213f 273 assert(u->meta.type != _UNIT_TYPE_INVALID);
c1e1601e
LP
274
275 if (u->meta.load_state == UNIT_STUB || u->meta.in_dbus_queue || set_isempty(u->meta.manager->subscribed))
276 return;
277
278 LIST_PREPEND(Meta, dbus_queue, u->meta.manager->dbus_unit_queue, &u->meta);
279 u->meta.in_dbus_queue = true;
280}
281
87f0e418
LP
282static void bidi_set_free(Unit *u, Set *s) {
283 Iterator i;
284 Unit *other;
285
286 assert(u);
287
288 /* Frees the set and makes sure we are dropped from the
289 * inverse pointers */
290
291 SET_FOREACH(other, s, i) {
292 UnitDependency d;
293
294 for (d = 0; d < _UNIT_DEPENDENCY_MAX; d++)
295 set_remove(other->meta.dependencies[d], u);
701cc384
LP
296
297 unit_add_to_gc_queue(other);
87f0e418
LP
298 }
299
300 set_free(s);
301}
302
303void unit_free(Unit *u) {
304 UnitDependency d;
305 Iterator i;
306 char *t;
307
308 assert(u);
309
c1e1601e
LP
310 bus_unit_send_removed_signal(u);
311
87f0e418 312 /* Detach from next 'bigger' objects */
87f0e418
LP
313 SET_FOREACH(t, u->meta.names, i)
314 hashmap_remove_value(u->meta.manager->units, t, u);
315
ef734fd6
LP
316 if (u->meta.type != _UNIT_TYPE_INVALID)
317 LIST_REMOVE(Meta, units_per_type, u->meta.manager->units_per_type[u->meta.type], &u->meta);
318
87f0e418
LP
319 if (u->meta.in_load_queue)
320 LIST_REMOVE(Meta, load_queue, u->meta.manager->load_queue, &u->meta);
321
c1e1601e
LP
322 if (u->meta.in_dbus_queue)
323 LIST_REMOVE(Meta, dbus_queue, u->meta.manager->dbus_unit_queue, &u->meta);
324
23a177ef
LP
325 if (u->meta.in_cleanup_queue)
326 LIST_REMOVE(Meta, cleanup_queue, u->meta.manager->cleanup_queue, &u->meta);
327
701cc384
LP
328 if (u->meta.in_gc_queue) {
329 LIST_REMOVE(Meta, gc_queue, u->meta.manager->gc_queue, &u->meta);
330 u->meta.manager->n_in_gc_queue--;
331 }
332
e537352b
LP
333 /* Free data and next 'smaller' objects */
334 if (u->meta.job)
335 job_free(u->meta.job);
336
23a177ef 337 if (u->meta.load_state != UNIT_STUB)
87f0e418
LP
338 if (UNIT_VTABLE(u)->done)
339 UNIT_VTABLE(u)->done(u);
340
e537352b 341 cgroup_bonding_free_list(u->meta.cgroup_bondings);
87f0e418
LP
342
343 for (d = 0; d < _UNIT_DEPENDENCY_MAX; d++)
344 bidi_set_free(u, u->meta.dependencies[d]);
345
346 free(u->meta.description);
6be1e7d5 347 free(u->meta.fragment_path);
87f0e418
LP
348
349 while ((t = set_steal_first(u->meta.names)))
350 free(t);
351 set_free(u->meta.names);
352
9e2f7c11
LP
353 free(u->meta.instance);
354
87f0e418
LP
355 free(u);
356}
357
358UnitActiveState unit_active_state(Unit *u) {
359 assert(u);
360
361 if (u->meta.load_state != UNIT_LOADED)
362 return UNIT_INACTIVE;
363
364 return UNIT_VTABLE(u)->active_state(u);
365}
366
10a94420
LP
367const char* unit_sub_state_to_string(Unit *u) {
368 assert(u);
369
370 return UNIT_VTABLE(u)->sub_state_to_string(u);
371}
372
23a177ef
LP
373static void complete_move(Set **s, Set **other) {
374 assert(s);
375 assert(other);
87f0e418 376
23a177ef
LP
377 if (!*other)
378 return;
87f0e418
LP
379
380 if (*s)
23a177ef
LP
381 set_move(*s, *other);
382 else {
383 *s = *other;
384 *other = NULL;
385 }
386}
87f0e418 387
23a177ef
LP
388static void merge_names(Unit *u, Unit *other) {
389 char *t;
390 Iterator i;
87f0e418 391
23a177ef
LP
392 assert(u);
393 assert(other);
394
395 complete_move(&u->meta.names, &other->meta.names);
396
397 while ((t = set_steal_first(other->meta.names)))
398 free(t);
399
400 set_free(other->meta.names);
401 other->meta.names = NULL;
402 other->meta.id = NULL;
403
404 SET_FOREACH(t, u->meta.names, i)
405 assert_se(hashmap_replace(u->meta.manager->units, t, u) == 0);
87f0e418
LP
406}
407
23a177ef
LP
408static void merge_dependencies(Unit *u, Unit *other, UnitDependency d) {
409 Iterator i;
410 Unit *back;
87f0e418 411 int r;
23a177ef
LP
412
413 assert(u);
414 assert(other);
415 assert(d < _UNIT_DEPENDENCY_MAX);
416
417 SET_FOREACH(back, other->meta.dependencies[d], i) {
418 UnitDependency k;
419
420 for (k = 0; k < _UNIT_DEPENDENCY_MAX; k++)
421 if ((r = set_remove_and_put(back->meta.dependencies[k], other, u)) < 0) {
422
423 if (r == -EEXIST)
424 set_remove(back->meta.dependencies[k], other);
425 else
426 assert(r == -ENOENT);
427 }
428 }
429
430 complete_move(&u->meta.dependencies[d], &other->meta.dependencies[d]);
431
432 set_free(other->meta.dependencies[d]);
433 other->meta.dependencies[d] = NULL;
434}
435
436int unit_merge(Unit *u, Unit *other) {
87f0e418
LP
437 UnitDependency d;
438
439 assert(u);
440 assert(other);
441 assert(u->meta.manager == other->meta.manager);
9e2f7c11 442 assert(u->meta.type != _UNIT_TYPE_INVALID);
87f0e418 443
cc916967
LP
444 other = unit_follow_merge(other);
445
23a177ef
LP
446 if (other == u)
447 return 0;
448
9e2f7c11
LP
449 if (u->meta.type != other->meta.type)
450 return -EINVAL;
451
452 if (!streq_ptr(u->meta.instance, other->meta.instance))
87f0e418
LP
453 return -EINVAL;
454
cc916967
LP
455 if (other->meta.load_state != UNIT_STUB &&
456 other->meta.load_state != UNIT_FAILED)
23a177ef 457 return -EEXIST;
87f0e418 458
819e213f
LP
459 if (other->meta.job)
460 return -EEXIST;
461
462 if (unit_active_state(other) != UNIT_INACTIVE)
463 return -EEXIST;
464
87f0e418 465 /* Merge names */
23a177ef 466 merge_names(u, other);
87f0e418
LP
467
468 /* Merge dependencies */
469 for (d = 0; d < _UNIT_DEPENDENCY_MAX; d++)
23a177ef 470 merge_dependencies(u, other, d);
87f0e418 471
23a177ef
LP
472 other->meta.load_state = UNIT_MERGED;
473 other->meta.merged_into = u;
474
3616a49c
LP
475 /* If there is still some data attached to the other node, we
476 * don't need it anymore, and can free it. */
477 if (other->meta.load_state != UNIT_STUB)
478 if (UNIT_VTABLE(other)->done)
479 UNIT_VTABLE(other)->done(other);
480
481 unit_add_to_dbus_queue(u);
23a177ef
LP
482 unit_add_to_cleanup_queue(other);
483
484 return 0;
485}
486
487int unit_merge_by_name(Unit *u, const char *name) {
488 Unit *other;
9e2f7c11
LP
489 int r;
490 char *s = NULL;
23a177ef
LP
491
492 assert(u);
493 assert(name);
494
9e2f7c11
LP
495 if (unit_name_is_template(name)) {
496 if (!u->meta.instance)
497 return -EINVAL;
498
499 if (!(s = unit_name_replace_instance(name, u->meta.instance)))
500 return -ENOMEM;
501
502 name = s;
503 }
504
23a177ef 505 if (!(other = manager_get_unit(u->meta.manager, name)))
9e2f7c11
LP
506 r = unit_add_name(u, name);
507 else
508 r = unit_merge(u, other);
23a177ef 509
9e2f7c11
LP
510 free(s);
511 return r;
23a177ef
LP
512}
513
514Unit* unit_follow_merge(Unit *u) {
515 assert(u);
516
517 while (u->meta.load_state == UNIT_MERGED)
518 assert_se(u = u->meta.merged_into);
519
520 return u;
521}
522
523int unit_add_exec_dependencies(Unit *u, ExecContext *c) {
524 int r;
525
526 assert(u);
527 assert(c);
528
80876c20 529 if (c->std_output != EXEC_OUTPUT_KERNEL && c->std_output != EXEC_OUTPUT_SYSLOG)
23a177ef
LP
530 return 0;
531
532 /* If syslog or kernel logging is requested, make sure our own
533 * logging daemon is run first. */
534
701cc384 535 if ((r = unit_add_dependency_by_name(u, UNIT_AFTER, SPECIAL_LOGGER_SOCKET, NULL, true)) < 0)
23a177ef
LP
536 return r;
537
538 if (u->meta.manager->running_as != MANAGER_SESSION)
701cc384 539 if ((r = unit_add_dependency_by_name(u, UNIT_REQUIRES, SPECIAL_LOGGER_SOCKET, NULL, true)) < 0)
23a177ef
LP
540 return r;
541
87f0e418
LP
542 return 0;
543}
544
87f0e418
LP
545const char *unit_description(Unit *u) {
546 assert(u);
547
548 if (u->meta.description)
549 return u->meta.description;
550
9e2f7c11 551 return u->meta.id;
87f0e418
LP
552}
553
554void unit_dump(Unit *u, FILE *f, const char *prefix) {
87f0e418
LP
555 char *t;
556 UnitDependency d;
557 Iterator i;
47be870b
LP
558 char *p2;
559 const char *prefix2;
8e274523 560 CGroupBonding *b;
173e3821
LP
561 char
562 timestamp1[FORMAT_TIMESTAMP_MAX],
563 timestamp2[FORMAT_TIMESTAMP_MAX],
564 timestamp3[FORMAT_TIMESTAMP_MAX],
565 timestamp4[FORMAT_TIMESTAMP_MAX];
87f0e418
LP
566
567 assert(u);
9e2f7c11 568 assert(u->meta.type >= 0);
87f0e418
LP
569
570 if (!prefix)
571 prefix = "";
47be870b
LP
572 p2 = strappend(prefix, "\t");
573 prefix2 = p2 ? p2 : prefix;
87f0e418
LP
574
575 fprintf(f,
40d50879 576 "%s-> Unit %s:\n"
87f0e418 577 "%s\tDescription: %s\n"
9e2f7c11 578 "%s\tInstance: %s\n"
87f0e418 579 "%s\tUnit Load State: %s\n"
2fad8195 580 "%s\tUnit Active State: %s\n"
173e3821 581 "%s\tInactive Exit Timestamp: %s\n"
2fad8195 582 "%s\tActive Enter Timestamp: %s\n"
701cc384 583 "%s\tActive Exit Timestamp: %s\n"
173e3821 584 "%s\tInactive Enter Timestamp: %s\n"
701cc384 585 "%s\tGC Check Good: %s\n",
9e2f7c11 586 prefix, u->meta.id,
87f0e418 587 prefix, unit_description(u),
9e2f7c11 588 prefix, strna(u->meta.instance),
94f04347 589 prefix, unit_load_state_to_string(u->meta.load_state),
2fad8195 590 prefix, unit_active_state_to_string(unit_active_state(u)),
173e3821
LP
591 prefix, strna(format_timestamp(timestamp1, sizeof(timestamp1), u->meta.inactive_exit_timestamp)),
592 prefix, strna(format_timestamp(timestamp2, sizeof(timestamp2), u->meta.active_enter_timestamp)),
593 prefix, strna(format_timestamp(timestamp3, sizeof(timestamp3), u->meta.active_exit_timestamp)),
594 prefix, strna(format_timestamp(timestamp4, sizeof(timestamp4), u->meta.inactive_enter_timestamp)),
701cc384 595 prefix, yes_no(unit_check_gc(u)));
0301abf4 596
87f0e418
LP
597 SET_FOREACH(t, u->meta.names, i)
598 fprintf(f, "%s\tName: %s\n", prefix, t);
599
23a177ef
LP
600 if (u->meta.fragment_path)
601 fprintf(f, "%s\tFragment Path: %s\n", prefix, u->meta.fragment_path);
602
87f0e418
LP
603 for (d = 0; d < _UNIT_DEPENDENCY_MAX; d++) {
604 Unit *other;
605
87f0e418 606 SET_FOREACH(other, u->meta.dependencies[d], i)
9e2f7c11 607 fprintf(f, "%s\t%s: %s\n", prefix, unit_dependency_to_string(d), other->meta.id);
87f0e418
LP
608 }
609
23a177ef 610 if (u->meta.load_state == UNIT_LOADED) {
b0650475
LP
611 fprintf(f,
612 "%s\tRecursive Stop: %s\n"
613 "%s\tStop When Unneeded: %s\n",
614 prefix, yes_no(u->meta.recursive_stop),
615 prefix, yes_no(u->meta.stop_when_unneeded));
616
23a177ef
LP
617 LIST_FOREACH(by_unit, b, u->meta.cgroup_bondings)
618 fprintf(f, "%s\tControlGroup: %s:%s\n",
619 prefix, b->controller, b->path);
8e274523 620
23a177ef
LP
621 if (UNIT_VTABLE(u)->dump)
622 UNIT_VTABLE(u)->dump(u, f, prefix2);
b0650475
LP
623
624 } else if (u->meta.load_state == UNIT_MERGED)
625 fprintf(f,
626 "%s\tMerged into: %s\n",
9e2f7c11 627 prefix, u->meta.merged_into->meta.id);
87f0e418
LP
628
629 if (u->meta.job)
630 job_dump(u->meta.job, f, prefix2);
631
47be870b 632 free(p2);
87f0e418
LP
633}
634
635/* Common implementation for multiple backends */
e537352b 636int unit_load_fragment_and_dropin(Unit *u) {
23a177ef
LP
637 int r;
638
639 assert(u);
23a177ef
LP
640
641 /* Load a .service file */
e537352b 642 if ((r = unit_load_fragment(u)) < 0)
23a177ef
LP
643 return r;
644
e537352b 645 if (u->meta.load_state == UNIT_STUB)
23a177ef
LP
646 return -ENOENT;
647
648 /* Load drop-in directory data */
649 if ((r = unit_load_dropin(unit_follow_merge(u))) < 0)
650 return r;
651
652 return 0;
653}
654
655/* Common implementation for multiple backends */
e537352b 656int unit_load_fragment_and_dropin_optional(Unit *u) {
23a177ef 657 int r;
87f0e418
LP
658
659 assert(u);
660
23a177ef
LP
661 /* Same as unit_load_fragment_and_dropin(), but whether
662 * something can be loaded or not doesn't matter. */
663
664 /* Load a .service file */
e537352b 665 if ((r = unit_load_fragment(u)) < 0)
87f0e418
LP
666 return r;
667
e537352b
LP
668 if (u->meta.load_state == UNIT_STUB)
669 u->meta.load_state = UNIT_LOADED;
d46de8a1 670
87f0e418 671 /* Load drop-in directory data */
23a177ef 672 if ((r = unit_load_dropin(unit_follow_merge(u))) < 0)
87f0e418
LP
673 return r;
674
23a177ef 675 return 0;
87f0e418
LP
676}
677
a16e1123
LP
678/* Common implementation for multiple backends */
679int unit_load_nop(Unit *u) {
680 assert(u);
681
682 if (u->meta.load_state == UNIT_STUB)
683 u->meta.load_state = UNIT_LOADED;
684
685 return 0;
686}
687
87f0e418
LP
688int unit_load(Unit *u) {
689 int r;
690
691 assert(u);
692
693 if (u->meta.in_load_queue) {
694 LIST_REMOVE(Meta, load_queue, u->meta.manager->load_queue, &u->meta);
695 u->meta.in_load_queue = false;
696 }
697
e537352b
LP
698 if (u->meta.type == _UNIT_TYPE_INVALID)
699 return -EINVAL;
700
87f0e418
LP
701 if (u->meta.load_state != UNIT_STUB)
702 return 0;
703
e537352b
LP
704 if (UNIT_VTABLE(u)->load)
705 if ((r = UNIT_VTABLE(u)->load(u)) < 0)
87f0e418 706 goto fail;
23a177ef 707
e537352b 708 if (u->meta.load_state == UNIT_STUB) {
23a177ef
LP
709 r = -ENOENT;
710 goto fail;
711 }
712
23a177ef
LP
713 assert((u->meta.load_state != UNIT_MERGED) == !u->meta.merged_into);
714
715 unit_add_to_dbus_queue(unit_follow_merge(u));
701cc384 716 unit_add_to_gc_queue(u);
87f0e418 717
87f0e418
LP
718 return 0;
719
720fail:
721 u->meta.load_state = UNIT_FAILED;
c1e1601e 722 unit_add_to_dbus_queue(u);
23a177ef 723
30de7d85 724 log_debug("Failed to load configuration for %s: %s", u->meta.id, strerror(-r));
23a177ef 725
87f0e418
LP
726 return r;
727}
728
729/* Errors:
730 * -EBADR: This unit type does not support starting.
731 * -EALREADY: Unit is already started.
732 * -EAGAIN: An operation is already in progress. Retry later.
733 */
734int unit_start(Unit *u) {
735 UnitActiveState state;
736
737 assert(u);
738
7898b0cf
LP
739 /* If this is already (being) started, then this will
740 * succeed. Note that this will even succeed if this unit is
741 * not startable by the user. This is relied on to detect when
742 * we need to wait for units and when waiting is finished. */
87f0e418
LP
743 state = unit_active_state(u);
744 if (UNIT_IS_ACTIVE_OR_RELOADING(state))
745 return -EALREADY;
746
7898b0cf
LP
747 /* If it is stopped, but we cannot start it, then fail */
748 if (!UNIT_VTABLE(u)->start)
749 return -EBADR;
750
87f0e418
LP
751 /* We don't suppress calls to ->start() here when we are
752 * already starting, to allow this request to be used as a
753 * "hurry up" call, for example when the unit is in some "auto
754 * restart" state where it waits for a holdoff timer to elapse
755 * before it will start again. */
756
c1e1601e 757 unit_add_to_dbus_queue(u);
87f0e418
LP
758 return UNIT_VTABLE(u)->start(u);
759}
760
761bool unit_can_start(Unit *u) {
762 assert(u);
763
764 return !!UNIT_VTABLE(u)->start;
765}
766
767/* Errors:
768 * -EBADR: This unit type does not support stopping.
769 * -EALREADY: Unit is already stopped.
770 * -EAGAIN: An operation is already in progress. Retry later.
771 */
772int unit_stop(Unit *u) {
773 UnitActiveState state;
774
775 assert(u);
776
87f0e418
LP
777 state = unit_active_state(u);
778 if (state == UNIT_INACTIVE)
779 return -EALREADY;
780
7898b0cf
LP
781 if (!UNIT_VTABLE(u)->stop)
782 return -EBADR;
783
c1e1601e 784 unit_add_to_dbus_queue(u);
87f0e418
LP
785 return UNIT_VTABLE(u)->stop(u);
786}
787
788/* Errors:
789 * -EBADR: This unit type does not support reloading.
790 * -ENOEXEC: Unit is not started.
791 * -EAGAIN: An operation is already in progress. Retry later.
792 */
793int unit_reload(Unit *u) {
794 UnitActiveState state;
795
796 assert(u);
797
798 if (!unit_can_reload(u))
799 return -EBADR;
800
801 state = unit_active_state(u);
802 if (unit_active_state(u) == UNIT_ACTIVE_RELOADING)
803 return -EALREADY;
804
805 if (unit_active_state(u) != UNIT_ACTIVE)
806 return -ENOEXEC;
807
c1e1601e 808 unit_add_to_dbus_queue(u);
87f0e418
LP
809 return UNIT_VTABLE(u)->reload(u);
810}
811
812bool unit_can_reload(Unit *u) {
813 assert(u);
814
815 if (!UNIT_VTABLE(u)->reload)
816 return false;
817
818 if (!UNIT_VTABLE(u)->can_reload)
819 return true;
820
821 return UNIT_VTABLE(u)->can_reload(u);
822}
823
f3bff0eb
LP
824static void unit_check_uneeded(Unit *u) {
825 Iterator i;
826 Unit *other;
827
828 assert(u);
829
830 /* If this service shall be shut down when unneeded then do
831 * so. */
832
833 if (!u->meta.stop_when_unneeded)
834 return;
835
836 if (!UNIT_IS_ACTIVE_OR_ACTIVATING(unit_active_state(u)))
837 return;
838
839 SET_FOREACH(other, u->meta.dependencies[UNIT_REQUIRED_BY], i)
840 if (!UNIT_IS_INACTIVE_OR_DEACTIVATING(unit_active_state(other)))
841 return;
842
9e2f7c11 843 SET_FOREACH(other, u->meta.dependencies[UNIT_REQUIRED_BY_OVERRIDABLE], i)
f3bff0eb
LP
844 if (!UNIT_IS_INACTIVE_OR_DEACTIVATING(unit_active_state(other)))
845 return;
846
847 SET_FOREACH(other, u->meta.dependencies[UNIT_WANTED_BY], i)
848 if (!UNIT_IS_INACTIVE_OR_DEACTIVATING(unit_active_state(other)))
849 return;
850
9e2f7c11 851 log_debug("Service %s is not needed anymore. Stopping.", u->meta.id);
f3bff0eb
LP
852
853 /* Ok, nobody needs us anymore. Sniff. Then let's commit suicide */
854 manager_add_job(u->meta.manager, JOB_STOP, u, JOB_FAIL, true, NULL);
855}
856
87f0e418
LP
857static void retroactively_start_dependencies(Unit *u) {
858 Iterator i;
859 Unit *other;
860
861 assert(u);
862 assert(UNIT_IS_ACTIVE_OR_ACTIVATING(unit_active_state(u)));
863
864 SET_FOREACH(other, u->meta.dependencies[UNIT_REQUIRES], i)
865 if (!UNIT_IS_ACTIVE_OR_ACTIVATING(unit_active_state(other)))
866 manager_add_job(u->meta.manager, JOB_START, other, JOB_REPLACE, true, NULL);
867
9e2f7c11 868 SET_FOREACH(other, u->meta.dependencies[UNIT_REQUIRES_OVERRIDABLE], i)
87f0e418
LP
869 if (!UNIT_IS_ACTIVE_OR_ACTIVATING(unit_active_state(other)))
870 manager_add_job(u->meta.manager, JOB_START, other, JOB_FAIL, false, NULL);
871
872 SET_FOREACH(other, u->meta.dependencies[UNIT_REQUISITE], i)
873 if (!UNIT_IS_ACTIVE_OR_ACTIVATING(unit_active_state(other)))
874 manager_add_job(u->meta.manager, JOB_START, other, JOB_REPLACE, true, NULL);
875
876 SET_FOREACH(other, u->meta.dependencies[UNIT_WANTS], i)
877 if (!UNIT_IS_ACTIVE_OR_ACTIVATING(unit_active_state(other)))
878 manager_add_job(u->meta.manager, JOB_START, other, JOB_FAIL, false, NULL);
879
880 SET_FOREACH(other, u->meta.dependencies[UNIT_CONFLICTS], i)
881 if (!UNIT_IS_ACTIVE_OR_ACTIVATING(unit_active_state(other)))
882 manager_add_job(u->meta.manager, JOB_STOP, other, JOB_REPLACE, true, NULL);
883}
884
885static void retroactively_stop_dependencies(Unit *u) {
886 Iterator i;
887 Unit *other;
888
889 assert(u);
890 assert(UNIT_IS_INACTIVE_OR_DEACTIVATING(unit_active_state(u)));
891
f3bff0eb
LP
892 if (u->meta.recursive_stop) {
893 /* Pull down units need us recursively if enabled */
894 SET_FOREACH(other, u->meta.dependencies[UNIT_REQUIRED_BY], i)
895 if (!UNIT_IS_INACTIVE_OR_DEACTIVATING(unit_active_state(other)))
896 manager_add_job(u->meta.manager, JOB_STOP, other, JOB_REPLACE, true, NULL);
897 }
898
899 /* Garbage collect services that might not be needed anymore, if enabled */
900 SET_FOREACH(other, u->meta.dependencies[UNIT_REQUIRES], i)
87f0e418 901 if (!UNIT_IS_INACTIVE_OR_DEACTIVATING(unit_active_state(other)))
f3bff0eb 902 unit_check_uneeded(other);
9e2f7c11 903 SET_FOREACH(other, u->meta.dependencies[UNIT_REQUIRES_OVERRIDABLE], i)
f3bff0eb
LP
904 if (!UNIT_IS_INACTIVE_OR_DEACTIVATING(unit_active_state(other)))
905 unit_check_uneeded(other);
906 SET_FOREACH(other, u->meta.dependencies[UNIT_WANTS], i)
907 if (!UNIT_IS_INACTIVE_OR_DEACTIVATING(unit_active_state(other)))
908 unit_check_uneeded(other);
909 SET_FOREACH(other, u->meta.dependencies[UNIT_REQUISITE], i)
910 if (!UNIT_IS_INACTIVE_OR_DEACTIVATING(unit_active_state(other)))
911 unit_check_uneeded(other);
9e2f7c11 912 SET_FOREACH(other, u->meta.dependencies[UNIT_REQUISITE_OVERRIDABLE], i)
f3bff0eb
LP
913 if (!UNIT_IS_INACTIVE_OR_DEACTIVATING(unit_active_state(other)))
914 unit_check_uneeded(other);
87f0e418
LP
915}
916
917void unit_notify(Unit *u, UnitActiveState os, UnitActiveState ns) {
a096ed36 918 bool unexpected = false;
173e3821 919 usec_t ts;
a096ed36 920
87f0e418
LP
921 assert(u);
922 assert(os < _UNIT_ACTIVE_STATE_MAX);
923 assert(ns < _UNIT_ACTIVE_STATE_MAX);
87f0e418 924
8e471ccd
LP
925 /* Note that this is called for all low-level state changes,
926 * even if they might map to the same high-level
927 * UnitActiveState! That means that ns == os is OK an expected
928 * behaviour here. For example: if a mount point is remounted
929 * this function will be called too and the utmp code below
930 * relies on that! */
87f0e418 931
173e3821
LP
932 ts = now(CLOCK_REALTIME);
933
934 if (os == UNIT_INACTIVE && ns != UNIT_INACTIVE)
935 u->meta.inactive_exit_timestamp = ts;
936 else if (os != UNIT_INACTIVE && ns == UNIT_INACTIVE)
937 u->meta.inactive_enter_timestamp = ts;
938
87f0e418 939 if (!UNIT_IS_ACTIVE_OR_RELOADING(os) && UNIT_IS_ACTIVE_OR_RELOADING(ns))
173e3821 940 u->meta.active_enter_timestamp = ts;
87f0e418 941 else if (UNIT_IS_ACTIVE_OR_RELOADING(os) && !UNIT_IS_ACTIVE_OR_RELOADING(ns))
173e3821 942 u->meta.active_exit_timestamp = ts;
87f0e418
LP
943
944 if (u->meta.job) {
945
946 if (u->meta.job->state == JOB_WAITING)
947
948 /* So we reached a different state for this
949 * job. Let's see if we can run it now if it
950 * failed previously due to EAGAIN. */
c1e1601e 951 job_add_to_run_queue(u->meta.job);
87f0e418
LP
952
953 else {
954 assert(u->meta.job->state == JOB_RUNNING);
955
f50e0a01 956 /* Let's check whether this state change
87f0e418
LP
957 * constitutes a finished job, or maybe
958 * cotradicts a running job and hence needs to
959 * invalidate jobs. */
960
961 switch (u->meta.job->type) {
962
963 case JOB_START:
964 case JOB_VERIFY_ACTIVE:
965
a096ed36 966 if (UNIT_IS_ACTIVE_OR_RELOADING(ns))
87f0e418 967 job_finish_and_invalidate(u->meta.job, true);
a096ed36
LP
968 else if (ns != UNIT_ACTIVATING) {
969 unexpected = true;
87f0e418 970 job_finish_and_invalidate(u->meta.job, false);
a096ed36 971 }
87f0e418
LP
972
973 break;
974
975 case JOB_RELOAD:
976 case JOB_RELOAD_OR_START:
977
a096ed36 978 if (ns == UNIT_ACTIVE)
87f0e418 979 job_finish_and_invalidate(u->meta.job, true);
a096ed36
LP
980 else if (ns != UNIT_ACTIVATING && ns != UNIT_ACTIVE_RELOADING) {
981 unexpected = true;
87f0e418 982 job_finish_and_invalidate(u->meta.job, false);
a096ed36 983 }
87f0e418
LP
984
985 break;
986
987 case JOB_STOP:
988 case JOB_RESTART:
989 case JOB_TRY_RESTART:
990
a096ed36 991 if (ns == UNIT_INACTIVE)
87f0e418 992 job_finish_and_invalidate(u->meta.job, true);
a096ed36
LP
993 else if (ns != UNIT_DEACTIVATING) {
994 unexpected = true;
87f0e418 995 job_finish_and_invalidate(u->meta.job, false);
a096ed36 996 }
87f0e418
LP
997
998 break;
999
1000 default:
1001 assert_not_reached("Job type unknown");
1002 }
1003 }
1004 }
1005
1006 /* If this state change happened without being requested by a
1007 * job, then let's retroactively start or stop dependencies */
1008
a096ed36
LP
1009 if (unexpected) {
1010 if (UNIT_IS_INACTIVE_OR_DEACTIVATING(os) && UNIT_IS_ACTIVE_OR_ACTIVATING(ns))
1011 retroactively_start_dependencies(u);
1012 else if (UNIT_IS_ACTIVE_OR_ACTIVATING(os) && UNIT_IS_INACTIVE_OR_DEACTIVATING(ns))
1013 retroactively_stop_dependencies(u);
1014 }
f3bff0eb 1015
e537352b
LP
1016 /* Some names are special */
1017 if (UNIT_IS_ACTIVE_OR_RELOADING(ns)) {
f278026d 1018 if (unit_has_name(u, SPECIAL_DBUS_SERVICE)) {
e537352b
LP
1019 /* The bus just might have become available,
1020 * hence try to connect to it, if we aren't
1021 * yet connected. */
f278026d
LP
1022 bus_init_system(u->meta.manager);
1023 bus_init_api(u->meta.manager);
1024 }
1025
e537352b
LP
1026 if (unit_has_name(u, SPECIAL_SYSLOG_SERVICE))
1027 /* The syslog daemon just might have become
1028 * available, hence try to connect to it, if
1029 * we aren't yet connected. */
843d2643 1030 log_open();
f278026d 1031
e537352b
LP
1032 if (u->meta.type == UNIT_MOUNT)
1033 /* Another directory became available, let's
1034 * check if that is enough to write our utmp
1035 * entry. */
1036 manager_write_utmp_reboot(u->meta.manager);
1037
1038 if (u->meta.type == UNIT_TARGET)
1039 /* A target got activated, maybe this is a runlevel? */
1040 manager_write_utmp_runlevel(u->meta.manager, u);
1041
1042 } else if (!UNIT_IS_ACTIVE_OR_RELOADING(ns)) {
f278026d
LP
1043
1044 if (unit_has_name(u, SPECIAL_SYSLOG_SERVICE))
e537352b
LP
1045 /* The syslog daemon might just have
1046 * terminated, hence try to disconnect from
1047 * it. */
2882c7ed 1048 log_close_syslog();
f278026d
LP
1049
1050 /* We don't care about D-Bus here, since we'll get an
1051 * asynchronous notification for it anyway. */
1052 }
1053
f3bff0eb
LP
1054 /* Maybe we finished startup and are now ready for being
1055 * stopped because unneeded? */
1056 unit_check_uneeded(u);
c1e1601e
LP
1057
1058 unit_add_to_dbus_queue(u);
701cc384 1059 unit_add_to_gc_queue(u);
87f0e418
LP
1060}
1061
acbb0225 1062int unit_watch_fd(Unit *u, int fd, uint32_t events, Watch *w) {
87f0e418
LP
1063 struct epoll_event ev;
1064
1065 assert(u);
1066 assert(fd >= 0);
acbb0225 1067 assert(w);
ea430986 1068 assert(w->type == WATCH_INVALID || (w->type == WATCH_FD && w->fd == fd && w->data.unit == u));
87f0e418
LP
1069
1070 zero(ev);
acbb0225 1071 ev.data.ptr = w;
87f0e418
LP
1072 ev.events = events;
1073
acbb0225
LP
1074 if (epoll_ctl(u->meta.manager->epoll_fd,
1075 w->type == WATCH_INVALID ? EPOLL_CTL_ADD : EPOLL_CTL_MOD,
1076 fd,
1077 &ev) < 0)
1078 return -errno;
87f0e418 1079
acbb0225
LP
1080 w->fd = fd;
1081 w->type = WATCH_FD;
ea430986 1082 w->data.unit = u;
87f0e418 1083
acbb0225 1084 return 0;
87f0e418
LP
1085}
1086
acbb0225 1087void unit_unwatch_fd(Unit *u, Watch *w) {
87f0e418 1088 assert(u);
acbb0225 1089 assert(w);
87f0e418 1090
acbb0225
LP
1091 if (w->type == WATCH_INVALID)
1092 return;
1093
ea430986
LP
1094 assert(w->type == WATCH_FD);
1095 assert(w->data.unit == u);
acbb0225
LP
1096 assert_se(epoll_ctl(u->meta.manager->epoll_fd, EPOLL_CTL_DEL, w->fd, NULL) >= 0);
1097
1098 w->fd = -1;
1099 w->type = WATCH_INVALID;
ea430986 1100 w->data.unit = NULL;
87f0e418
LP
1101}
1102
1103int unit_watch_pid(Unit *u, pid_t pid) {
1104 assert(u);
1105 assert(pid >= 1);
1106
05e343b7
LP
1107 /* Watch a specific PID. We only support one unit watching
1108 * each PID for now. */
1109
87f0e418
LP
1110 return hashmap_put(u->meta.manager->watch_pids, UINT32_TO_PTR(pid), u);
1111}
1112
1113void unit_unwatch_pid(Unit *u, pid_t pid) {
1114 assert(u);
1115 assert(pid >= 1);
1116
05e343b7 1117 hashmap_remove_value(u->meta.manager->watch_pids, UINT32_TO_PTR(pid), u);
87f0e418
LP
1118}
1119
acbb0225 1120int unit_watch_timer(Unit *u, usec_t delay, Watch *w) {
87f0e418 1121 struct itimerspec its;
acbb0225 1122 int flags, fd;
87f0e418
LP
1123 bool ours;
1124
1125 assert(u);
acbb0225 1126 assert(w);
ea430986 1127 assert(w->type == WATCH_INVALID || (w->type == WATCH_TIMER && w->data.unit == u));
87f0e418
LP
1128
1129 /* This will try to reuse the old timer if there is one */
1130
acbb0225 1131 if (w->type == WATCH_TIMER) {
87f0e418 1132 ours = false;
acbb0225 1133 fd = w->fd;
87f0e418
LP
1134 } else {
1135 ours = true;
87f0e418
LP
1136 if ((fd = timerfd_create(CLOCK_MONOTONIC, TFD_NONBLOCK|TFD_CLOEXEC)) < 0)
1137 return -errno;
1138 }
1139
1140 zero(its);
1141
1142 if (delay <= 0) {
1143 /* Set absolute time in the past, but not 0, since we
1144 * don't want to disarm the timer */
1145 its.it_value.tv_sec = 0;
1146 its.it_value.tv_nsec = 1;
1147
1148 flags = TFD_TIMER_ABSTIME;
1149 } else {
1150 timespec_store(&its.it_value, delay);
1151 flags = 0;
1152 }
1153
1154 /* This will also flush the elapse counter */
1155 if (timerfd_settime(fd, flags, &its, NULL) < 0)
1156 goto fail;
1157
acbb0225
LP
1158 if (w->type == WATCH_INVALID) {
1159 struct epoll_event ev;
87f0e418 1160
acbb0225
LP
1161 zero(ev);
1162 ev.data.ptr = w;
f94ea366 1163 ev.events = EPOLLIN;
acbb0225
LP
1164
1165 if (epoll_ctl(u->meta.manager->epoll_fd, EPOLL_CTL_ADD, fd, &ev) < 0)
1166 goto fail;
1167 }
1168
1169 w->fd = fd;
1170 w->type = WATCH_TIMER;
ea430986 1171 w->data.unit = u;
87f0e418 1172
87f0e418
LP
1173 return 0;
1174
1175fail:
1176 if (ours)
ea430986 1177 close_nointr_nofail(fd);
87f0e418
LP
1178
1179 return -errno;
1180}
1181
acbb0225 1182void unit_unwatch_timer(Unit *u, Watch *w) {
87f0e418 1183 assert(u);
acbb0225 1184 assert(w);
87f0e418 1185
acbb0225 1186 if (w->type == WATCH_INVALID)
87f0e418
LP
1187 return;
1188
ea430986 1189 assert(w->type == WATCH_TIMER && w->data.unit == u);
acbb0225
LP
1190
1191 assert_se(epoll_ctl(u->meta.manager->epoll_fd, EPOLL_CTL_DEL, w->fd, NULL) >= 0);
a16e1123 1192 close_nointr_nofail(w->fd);
acbb0225
LP
1193
1194 w->fd = -1;
1195 w->type = WATCH_INVALID;
ea430986 1196 w->data.unit = NULL;
87f0e418
LP
1197}
1198
1199bool unit_job_is_applicable(Unit *u, JobType j) {
1200 assert(u);
1201 assert(j >= 0 && j < _JOB_TYPE_MAX);
1202
1203 switch (j) {
1204
1205 case JOB_VERIFY_ACTIVE:
1206 case JOB_START:
1207 return true;
1208
1209 case JOB_STOP:
1210 case JOB_RESTART:
1211 case JOB_TRY_RESTART:
1212 return unit_can_start(u);
1213
1214 case JOB_RELOAD:
1215 return unit_can_reload(u);
1216
1217 case JOB_RELOAD_OR_START:
1218 return unit_can_reload(u) && unit_can_start(u);
1219
1220 default:
1221 assert_not_reached("Invalid job type");
1222 }
1223}
1224
701cc384 1225int unit_add_dependency(Unit *u, UnitDependency d, Unit *other, bool add_reference) {
87f0e418
LP
1226
1227 static const UnitDependency inverse_table[_UNIT_DEPENDENCY_MAX] = {
1228 [UNIT_REQUIRES] = UNIT_REQUIRED_BY,
9e2f7c11 1229 [UNIT_REQUIRES_OVERRIDABLE] = UNIT_REQUIRED_BY_OVERRIDABLE,
87f0e418
LP
1230 [UNIT_WANTS] = UNIT_WANTED_BY,
1231 [UNIT_REQUISITE] = UNIT_REQUIRED_BY,
9e2f7c11 1232 [UNIT_REQUISITE_OVERRIDABLE] = UNIT_REQUIRED_BY_OVERRIDABLE,
87f0e418 1233 [UNIT_REQUIRED_BY] = _UNIT_DEPENDENCY_INVALID,
9e2f7c11 1234 [UNIT_REQUIRED_BY_OVERRIDABLE] = _UNIT_DEPENDENCY_INVALID,
87f0e418
LP
1235 [UNIT_WANTED_BY] = _UNIT_DEPENDENCY_INVALID,
1236 [UNIT_CONFLICTS] = UNIT_CONFLICTS,
1237 [UNIT_BEFORE] = UNIT_AFTER,
701cc384
LP
1238 [UNIT_AFTER] = UNIT_BEFORE,
1239 [UNIT_REFERENCES] = UNIT_REFERENCED_BY,
1240 [UNIT_REFERENCED_BY] = UNIT_REFERENCES
87f0e418 1241 };
701cc384 1242 int r, q = 0, v = 0, w = 0;
87f0e418
LP
1243
1244 assert(u);
1245 assert(d >= 0 && d < _UNIT_DEPENDENCY_MAX);
1246 assert(inverse_table[d] != _UNIT_DEPENDENCY_INVALID);
1247 assert(other);
1248
1249 /* We won't allow dependencies on ourselves. We will not
1250 * consider them an error however. */
1251 if (u == other)
1252 return 0;
1253
9e2f7c11
LP
1254 if (UNIT_VTABLE(u)->no_requires &&
1255 (d == UNIT_REQUIRES ||
1256 d == UNIT_REQUIRES_OVERRIDABLE ||
1257 d == UNIT_REQUISITE ||
1258 d == UNIT_REQUISITE_OVERRIDABLE)) {
1259 return -EINVAL;
1260 }
1261
701cc384
LP
1262 if ((r = set_ensure_allocated(&u->meta.dependencies[d], trivial_hash_func, trivial_compare_func)) < 0 ||
1263 (r = set_ensure_allocated(&other->meta.dependencies[inverse_table[d]], trivial_hash_func, trivial_compare_func)) < 0)
87f0e418
LP
1264 return r;
1265
701cc384
LP
1266 if (add_reference)
1267 if ((r = set_ensure_allocated(&u->meta.dependencies[UNIT_REFERENCES], trivial_hash_func, trivial_compare_func)) < 0 ||
1268 (r = set_ensure_allocated(&other->meta.dependencies[UNIT_REFERENCED_BY], trivial_hash_func, trivial_compare_func)) < 0)
1269 return r;
87f0e418 1270
701cc384
LP
1271 if ((q = set_put(u->meta.dependencies[d], other)) < 0)
1272 return q;
87f0e418 1273
701cc384
LP
1274 if ((v = set_put(other->meta.dependencies[inverse_table[d]], u)) < 0) {
1275 r = v;
1276 goto fail;
1277 }
1278
1279 if (add_reference) {
1280 if ((w = set_put(u->meta.dependencies[UNIT_REFERENCES], other)) < 0) {
1281 r = w;
1282 goto fail;
1283 }
1284
1285 if ((r = set_put(other->meta.dependencies[UNIT_REFERENCED_BY], u)) < 0)
1286 goto fail;
87f0e418
LP
1287 }
1288
c1e1601e 1289 unit_add_to_dbus_queue(u);
87f0e418 1290 return 0;
701cc384
LP
1291
1292fail:
1293 if (q > 0)
1294 set_remove(u->meta.dependencies[d], other);
1295
1296 if (v > 0)
1297 set_remove(other->meta.dependencies[inverse_table[d]], u);
1298
1299 if (w > 0)
1300 set_remove(u->meta.dependencies[UNIT_REFERENCES], other);
1301
1302 return r;
87f0e418 1303}
0301abf4 1304
9e2f7c11
LP
1305static const char *resolve_template(Unit *u, const char *name, const char*path, char **p) {
1306 char *s;
1307
1308 assert(u);
1309 assert(name || path);
1310
1311 if (!name)
1312 name = file_name_from_path(path);
1313
1314 if (!unit_name_is_template(name)) {
1315 *p = NULL;
1316 return name;
1317 }
1318
1319 if (u->meta.instance)
1320 s = unit_name_replace_instance(name, u->meta.instance);
1321 else {
1322 char *i;
1323
1324 if (!(i = unit_name_to_prefix(u->meta.id)))
1325 return NULL;
1326
1327 s = unit_name_replace_instance(name, i);
1328 free(i);
1329 }
1330
1331 if (!s)
1332 return NULL;
1333
1334 *p = s;
1335 return s;
1336}
1337
701cc384 1338int unit_add_dependency_by_name(Unit *u, UnitDependency d, const char *name, const char *path, bool add_reference) {
09b6b09f
LP
1339 Unit *other;
1340 int r;
9e2f7c11 1341 char *s;
09b6b09f 1342
9e2f7c11
LP
1343 assert(u);
1344 assert(name || path);
09b6b09f 1345
9e2f7c11
LP
1346 if (!(name = resolve_template(u, name, path, &s)))
1347 return -ENOMEM;
09b6b09f 1348
9e2f7c11
LP
1349 if ((r = manager_load_unit(u->meta.manager, name, path, &other)) < 0)
1350 goto finish;
1351
701cc384 1352 r = unit_add_dependency(u, d, other, add_reference);
9e2f7c11
LP
1353
1354finish:
1355 free(s);
1356 return r;
09b6b09f
LP
1357}
1358
701cc384 1359int unit_add_dependency_by_name_inverse(Unit *u, UnitDependency d, const char *name, const char *path, bool add_reference) {
bd77d0fc
LP
1360 Unit *other;
1361 int r;
9e2f7c11 1362 char *s;
bd77d0fc 1363
9e2f7c11
LP
1364 assert(u);
1365 assert(name || path);
bd77d0fc 1366
9e2f7c11
LP
1367 if (!(name = resolve_template(u, name, path, &s)))
1368 return -ENOMEM;
bd77d0fc 1369
9e2f7c11
LP
1370 if ((r = manager_load_unit(u->meta.manager, name, path, &other)) < 0)
1371 goto finish;
1372
701cc384 1373 r = unit_add_dependency(other, d, u, add_reference);
9e2f7c11
LP
1374
1375finish:
1376 free(s);
1377 return r;
bd77d0fc
LP
1378}
1379
0301abf4
LP
1380int set_unit_path(const char *p) {
1381 char *cwd, *c;
1382 int r;
1383
1384 /* This is mostly for debug purposes */
1385
1386 if (path_is_absolute(p)) {
1387 if (!(c = strdup(p)))
1388 return -ENOMEM;
1389 } else {
1390 if (!(cwd = get_current_dir_name()))
1391 return -errno;
1392
1393 r = asprintf(&c, "%s/%s", cwd, p);
1394 free(cwd);
1395
1396 if (r < 0)
1397 return -ENOMEM;
1398 }
1399
036643a2 1400 if (setenv("SYSTEMD_UNIT_PATH", c, 0) < 0) {
0301abf4
LP
1401 r = -errno;
1402 free(c);
1403 return r;
1404 }
1405
1406 return 0;
1407}
88066b3a 1408
ea430986
LP
1409char *unit_dbus_path(Unit *u) {
1410 char *p, *e;
1411
1412 assert(u);
1413
9e2f7c11 1414 if (!(e = bus_path_escape(u->meta.id)))
ea430986
LP
1415 return NULL;
1416
1417 if (asprintf(&p, "/org/freedesktop/systemd1/unit/%s", e) < 0) {
1418 free(e);
1419 return NULL;
1420 }
1421
1422 free(e);
1423 return p;
1424}
1425
8e274523
LP
1426int unit_add_cgroup(Unit *u, CGroupBonding *b) {
1427 CGroupBonding *l;
1428 int r;
1429
1430 assert(u);
1431 assert(b);
1432 assert(b->path);
1433
1434 /* Ensure this hasn't been added yet */
1435 assert(!b->unit);
1436
1437 l = hashmap_get(u->meta.manager->cgroup_bondings, b->path);
1438 LIST_PREPEND(CGroupBonding, by_path, l, b);
1439
1440 if ((r = hashmap_replace(u->meta.manager->cgroup_bondings, b->path, l)) < 0) {
1441 LIST_REMOVE(CGroupBonding, by_path, l, b);
1442 return r;
1443 }
1444
1445 LIST_PREPEND(CGroupBonding, by_unit, u->meta.cgroup_bondings, b);
1446 b->unit = u;
1447
1448 return 0;
1449}
1450
013b87c0
LP
1451static char *default_cgroup_path(Unit *u) {
1452 char *p;
4f2d528d 1453 int r;
013b87c0
LP
1454
1455 assert(u);
1456
4f2d528d
LP
1457 if (u->meta.instance) {
1458 char *t;
013b87c0 1459
4f2d528d
LP
1460 if (!(t = unit_name_template(u->meta.id)))
1461 return NULL;
1462
1463 r = asprintf(&p, "%s/%s/%s", u->meta.manager->cgroup_hierarchy, t, u->meta.instance);
1464 free(t);
1465 } else
1466 r = asprintf(&p, "%s/%s", u->meta.manager->cgroup_hierarchy, u->meta.id);
1467
1468 return r < 0 ? NULL : p;
013b87c0
LP
1469}
1470
8e274523
LP
1471int unit_add_cgroup_from_text(Unit *u, const char *name) {
1472 size_t n;
013b87c0
LP
1473 char *controller = NULL, *path = NULL;
1474 CGroupBonding *b = NULL;
8e274523
LP
1475 int r;
1476
1477 assert(u);
1478 assert(name);
1479
1480 /* Detect controller name */
013b87c0 1481 n = strcspn(name, ":");
8e274523 1482
013b87c0
LP
1483 if (name[n] == 0 ||
1484 (name[n] == ':' && name[n+1] == 0)) {
8e274523 1485
013b87c0 1486 /* Only controller name, no path? */
8e274523 1487
013b87c0
LP
1488 if (!(path = default_cgroup_path(u)))
1489 return -ENOMEM;
8e274523 1490
013b87c0
LP
1491 } else {
1492 const char *p;
8e274523 1493
013b87c0
LP
1494 /* Controller name, and path. */
1495 p = name+n+1;
8e274523 1496
013b87c0
LP
1497 if (!path_is_absolute(p))
1498 return -EINVAL;
1499
1500 if (!(path = strdup(p)))
1501 return -ENOMEM;
8e274523
LP
1502 }
1503
013b87c0
LP
1504 if (n > 0)
1505 controller = strndup(name, n);
1506 else
1507 controller = strdup(u->meta.manager->cgroup_controller);
1508
1509 if (!controller) {
1510 r = -ENOMEM;
1511 goto fail;
8e274523
LP
1512 }
1513
013b87c0
LP
1514 if (cgroup_bonding_find_list(u->meta.cgroup_bondings, controller)) {
1515 r = -EEXIST;
1516 goto fail;
1517 }
8e274523 1518
013b87c0 1519 if (!(b = new0(CGroupBonding, 1))) {
8e274523
LP
1520 r = -ENOMEM;
1521 goto fail;
1522 }
1523
013b87c0
LP
1524 b->controller = controller;
1525 b->path = path;
8e274523
LP
1526 b->only_us = false;
1527 b->clean_up = false;
1528
1529 if ((r = unit_add_cgroup(u, b)) < 0)
1530 goto fail;
1531
1532 return 0;
1533
1534fail:
013b87c0
LP
1535 free(path);
1536 free(controller);
8e274523
LP
1537 free(b);
1538
1539 return r;
1540}
1541
1542int unit_add_default_cgroup(Unit *u) {
1543 CGroupBonding *b;
1544 int r = -ENOMEM;
1545
1546 assert(u);
1547
1548 /* Adds in the default cgroup data, if it wasn't specified yet */
1549
1550 if (unit_get_default_cgroup(u))
1551 return 0;
1552
1553 if (!(b = new0(CGroupBonding, 1)))
1554 return -ENOMEM;
1555
1556 if (!(b->controller = strdup(u->meta.manager->cgroup_controller)))
1557 goto fail;
1558
013b87c0 1559 if (!(b->path = default_cgroup_path(u)))
8e274523
LP
1560 goto fail;
1561
1562 b->clean_up = true;
1563 b->only_us = true;
1564
1565 if ((r = unit_add_cgroup(u, b)) < 0)
1566 goto fail;
1567
1568 return 0;
1569
1570fail:
1571 free(b->path);
1572 free(b->controller);
1573 free(b);
1574
1575 return r;
1576}
1577
1578CGroupBonding* unit_get_default_cgroup(Unit *u) {
1579 assert(u);
1580
1581 return cgroup_bonding_find_list(u->meta.cgroup_bondings, u->meta.manager->cgroup_controller);
1582}
1583
f6ff8c29
LP
1584int unit_load_related_unit(Unit *u, const char *type, Unit **_found) {
1585 char *t;
1586 int r;
1587
1588 assert(u);
1589 assert(type);
1590 assert(_found);
1591
9e2f7c11 1592 if (!(t = unit_name_change_suffix(u->meta.id, type)))
f6ff8c29
LP
1593 return -ENOMEM;
1594
1595 assert(!unit_has_name(u, t));
1596
9e2f7c11 1597 r = manager_load_unit(u->meta.manager, t, NULL, _found);
f6ff8c29
LP
1598 free(t);
1599
9e2f7c11 1600 assert(r < 0 || *_found != u);
f6ff8c29
LP
1601
1602 return r;
1603}
1604
a16e1123
LP
1605int unit_get_related_unit(Unit *u, const char *type, Unit **_found) {
1606 Unit *found;
1607 char *t;
1608
1609 assert(u);
1610 assert(type);
1611 assert(_found);
1612
1613 if (!(t = unit_name_change_suffix(u->meta.id, type)))
1614 return -ENOMEM;
1615
1616 assert(!unit_has_name(u, t));
1617
1618 found = manager_get_unit(u->meta.manager, t);
1619 free(t);
1620
1621 if (!found)
1622 return -ENOENT;
1623
1624 *_found = found;
1625 return 0;
1626}
1627
9e2f7c11
LP
1628static char *specifier_prefix_and_instance(char specifier, void *data, void *userdata) {
1629 Unit *u = userdata;
1630 assert(u);
1631
1632 return unit_name_to_prefix_and_instance(u->meta.id);
1633}
1634
1635static char *specifier_prefix(char specifier, void *data, void *userdata) {
1636 Unit *u = userdata;
1637 assert(u);
1638
1639 return unit_name_to_prefix(u->meta.id);
1640}
1641
1642static char *specifier_prefix_unescaped(char specifier, void *data, void *userdata) {
1643 Unit *u = userdata;
1644 char *p, *r;
1645
1646 assert(u);
1647
1648 if (!(p = unit_name_to_prefix(u->meta.id)))
1649 return NULL;
1650
1651 r = unit_name_unescape(p);
1652 free(p);
1653
1654 return r;
1655}
1656
1657static char *specifier_instance_unescaped(char specifier, void *data, void *userdata) {
1658 Unit *u = userdata;
1659 assert(u);
1660
1661 if (u->meta.instance)
1662 return unit_name_unescape(u->meta.instance);
1663
1664 return strdup("");
1665}
1666
1667char *unit_name_printf(Unit *u, const char* format) {
1668
1669 /*
1670 * This will use the passed string as format string and
1671 * replace the following specifiers:
1672 *
1673 * %n: the full id of the unit (foo@bar.waldo)
1674 * %N: the id of the unit without the suffix (foo@bar)
1675 * %p: the prefix (foo)
1676 * %i: the instance (bar)
1677 */
1678
1679 const Specifier table[] = {
1680 { 'n', specifier_string, u->meta.id },
1681 { 'N', specifier_prefix_and_instance, NULL },
1682 { 'p', specifier_prefix, NULL },
1683 { 'i', specifier_string, u->meta.instance },
1684 { 0, NULL, NULL }
1685 };
1686
1687 assert(u);
1688 assert(format);
1689
1690 return specifier_printf(format, table, u);
1691}
1692
1693char *unit_full_printf(Unit *u, const char *format) {
1694
1695 /* This is similar to unit_name_printf() but also supports
1696 * unescaping */
1697
1698 const Specifier table[] = {
1699 { 'n', specifier_string, u->meta.id },
1700 { 'N', specifier_prefix_and_instance, NULL },
1701 { 'p', specifier_prefix, NULL },
1702 { 'P', specifier_prefix_unescaped, NULL },
1703 { 'i', specifier_string, u->meta.instance },
1704 { 'I', specifier_instance_unescaped, NULL },
1705 { 0, NULL, NULL }
1706 };
1707
1708 assert(u);
1709 assert(format);
1710
1711 return specifier_printf(format, table, u);
1712}
1713
1714char **unit_full_printf_strv(Unit *u, char **l) {
1715 size_t n;
1716 char **r, **i, **j;
1717
1718 /* Applies unit_full_printf to every entry in l */
1719
1720 assert(u);
1721
1722 n = strv_length(l);
1723 if (!(r = new(char*, n+1)))
1724 return NULL;
1725
1726 for (i = l, j = r; *i; i++, j++)
1727 if (!(*j = unit_full_printf(u, *i)))
1728 goto fail;
1729
1730 *j = NULL;
1731 return r;
1732
1733fail:
1734 j--;
1735 while (j >= r)
1736 free(*j);
1737
1738 free(r);
1739
1740 return NULL;
1741}
1742
05e343b7
LP
1743int unit_watch_bus_name(Unit *u, const char *name) {
1744 assert(u);
1745 assert(name);
1746
1747 /* Watch a specific name on the bus. We only support one unit
1748 * watching each name for now. */
1749
1750 return hashmap_put(u->meta.manager->watch_bus, name, u);
1751}
1752
1753void unit_unwatch_bus_name(Unit *u, const char *name) {
1754 assert(u);
1755 assert(name);
1756
1757 hashmap_remove_value(u->meta.manager->watch_bus, name, u);
1758}
1759
a16e1123
LP
1760bool unit_can_serialize(Unit *u) {
1761 assert(u);
1762
1763 return UNIT_VTABLE(u)->serialize && UNIT_VTABLE(u)->deserialize_item;
1764}
1765
1766int unit_serialize(Unit *u, FILE *f, FDSet *fds) {
1767 int r;
1768
1769 assert(u);
1770 assert(f);
1771 assert(fds);
1772
1773 if (!unit_can_serialize(u))
1774 return 0;
1775
1776 if ((r = UNIT_VTABLE(u)->serialize(u, f, fds)) < 0)
1777 return r;
1778
1779 /* End marker */
1780 fputc('\n', f);
1781 return 0;
1782}
1783
1784void unit_serialize_item_format(Unit *u, FILE *f, const char *key, const char *format, ...) {
1785 va_list ap;
1786
1787 assert(u);
1788 assert(f);
1789 assert(key);
1790 assert(format);
1791
1792 fputs(key, f);
1793 fputc('=', f);
1794
1795 va_start(ap, format);
1796 vfprintf(f, format, ap);
1797 va_end(ap);
1798
1799 fputc('\n', f);
1800}
1801
1802void unit_serialize_item(Unit *u, FILE *f, const char *key, const char *value) {
1803 assert(u);
1804 assert(f);
1805 assert(key);
1806 assert(value);
1807
1808 fprintf(f, "%s=%s\n", key, value);
1809}
1810
1811int unit_deserialize(Unit *u, FILE *f, FDSet *fds) {
1812 int r;
1813
1814 assert(u);
1815 assert(f);
1816 assert(fds);
1817
1818 if (!unit_can_serialize(u))
1819 return 0;
1820
1821 for (;;) {
1822 char line[1024], *l, *v;
1823 size_t k;
1824
1825 if (!fgets(line, sizeof(line), f)) {
1826 if (feof(f))
1827 return 0;
1828 return -errno;
1829 }
1830
1831 l = strstrip(line);
1832
1833 /* End marker */
1834 if (l[0] == 0)
1835 return 0;
1836
1837 k = strcspn(l, "=");
1838
1839 if (l[k] == '=') {
1840 l[k] = 0;
1841 v = l+k+1;
1842 } else
1843 v = l+k;
1844
1845 if ((r = UNIT_VTABLE(u)->deserialize_item(u, l, v, fds)) < 0)
1846 return r;
1847 }
1848}
1849
6e2ef85b
LP
1850int unit_add_node_link(Unit *u, const char *what, bool wants) {
1851 Unit *device;
1852 char *e;
1853 int r;
1854
1855 assert(u);
1856
1857 if (!what)
1858 return 0;
1859
1860 /* Adds in links to the device node that this unit is based on */
1861
1862 if (!path_startswith(what, "/dev/") && !path_startswith(what, "/sys/"))
1863 return 0;
1864
1865 if (!(e = unit_name_build_escape(what+1, NULL, ".device")))
1866 return -ENOMEM;
1867
1868 r = manager_load_unit(u->meta.manager, e, NULL, &device);
1869 free(e);
1870
1871 if (r < 0)
1872 return r;
1873
1874 if ((r = unit_add_dependency(u, UNIT_AFTER, device, true)) < 0)
1875 return r;
1876
1877 if ((r = unit_add_dependency(u, UNIT_REQUIRES, device, true)) < 0)
1878 return r;
1879
1880 if (wants)
1881 if ((r = unit_add_dependency(device, UNIT_WANTS, u, false)) < 0)
1882 return r;
1883
1884 return 0;
1885}
a16e1123 1886
94f04347
LP
1887static const char* const unit_type_table[_UNIT_TYPE_MAX] = {
1888 [UNIT_SERVICE] = "service",
1889 [UNIT_TIMER] = "timer",
1890 [UNIT_SOCKET] = "socket",
1891 [UNIT_TARGET] = "target",
1892 [UNIT_DEVICE] = "device",
1893 [UNIT_MOUNT] = "mount",
1894 [UNIT_AUTOMOUNT] = "automount",
07b0b134
ML
1895 [UNIT_SNAPSHOT] = "snapshot",
1896 [UNIT_SWAP] = "swap"
94f04347
LP
1897};
1898
1899DEFINE_STRING_TABLE_LOOKUP(unit_type, UnitType);
1900
1901static const char* const unit_load_state_table[_UNIT_LOAD_STATE_MAX] = {
1902 [UNIT_STUB] = "stub",
1903 [UNIT_LOADED] = "loaded",
23a177ef
LP
1904 [UNIT_FAILED] = "failed",
1905 [UNIT_MERGED] = "merged"
94f04347
LP
1906};
1907
1908DEFINE_STRING_TABLE_LOOKUP(unit_load_state, UnitLoadState);
1909
1910static const char* const unit_active_state_table[_UNIT_ACTIVE_STATE_MAX] = {
1911 [UNIT_ACTIVE] = "active",
1912 [UNIT_INACTIVE] = "inactive",
1913 [UNIT_ACTIVATING] = "activating",
1914 [UNIT_DEACTIVATING] = "deactivating"
1915};
1916
1917DEFINE_STRING_TABLE_LOOKUP(unit_active_state, UnitActiveState);
1918
1919static const char* const unit_dependency_table[_UNIT_DEPENDENCY_MAX] = {
1920 [UNIT_REQUIRES] = "Requires",
9e2f7c11 1921 [UNIT_REQUIRES_OVERRIDABLE] = "RequiresOverridable",
94f04347
LP
1922 [UNIT_WANTS] = "Wants",
1923 [UNIT_REQUISITE] = "Requisite",
9e2f7c11 1924 [UNIT_REQUISITE_OVERRIDABLE] = "RequisiteOverridable",
94f04347 1925 [UNIT_REQUIRED_BY] = "RequiredBy",
9e2f7c11 1926 [UNIT_REQUIRED_BY_OVERRIDABLE] = "RequiredByOverridable",
94f04347
LP
1927 [UNIT_WANTED_BY] = "WantedBy",
1928 [UNIT_CONFLICTS] = "Conflicts",
1929 [UNIT_BEFORE] = "Before",
1930 [UNIT_AFTER] = "After",
701cc384
LP
1931 [UNIT_REFERENCES] = "References",
1932 [UNIT_REFERENCED_BY] = "ReferencedBy"
94f04347
LP
1933};
1934
1935DEFINE_STRING_TABLE_LOOKUP(unit_dependency, UnitDependency);
50159e6a
LP
1936
1937static const char* const kill_mode_table[_KILL_MODE_MAX] = {
80876c20 1938 [KILL_CONTROL_GROUP] = "control-group",
50159e6a 1939 [KILL_PROCESS_GROUP] = "process-group",
80876c20
LP
1940 [KILL_PROCESS] = "process",
1941 [KILL_NONE] = "none"
50159e6a
LP
1942};
1943
1944DEFINE_STRING_TABLE_LOOKUP(kill_mode, KillMode);