128
131
/* Ensure that this unit is either instanced or not instanced,
129
132
* but not both. */
130
if (u->meta.type != _UNIT_TYPE_INVALID && !u->meta.instance != !i) {
133
if (u->type != _UNIT_TYPE_INVALID && !u->instance != !i) {
135
138
if (unit_vtable[t]->no_alias &&
136
!set_isempty(u->meta.names) &&
137
!set_get(u->meta.names, s)) {
139
!set_isempty(u->names) &&
140
!set_get(u->names, s)) {
142
if (hashmap_size(u->meta.manager->units) >= MANAGER_MAX_NAMES) {
145
if (hashmap_size(u->manager->units) >= MANAGER_MAX_NAMES) {
147
if ((r = set_put(u->meta.names, s)) < 0) {
150
if ((r = set_put(u->names, s)) < 0) {
148
151
if (r == -EEXIST)
153
if ((r = hashmap_put(u->meta.manager->units, s, u)) < 0) {
154
set_remove(u->meta.names, s);
156
if ((r = hashmap_put(u->manager->units, s, u)) < 0) {
157
set_remove(u->names, s);
158
if (u->meta.type == _UNIT_TYPE_INVALID) {
162
u->meta.instance = i;
164
LIST_PREPEND(Meta, units_by_type, u->meta.manager->units_by_type[t], &u->meta);
161
if (u->type == _UNIT_TYPE_INVALID) {
167
LIST_PREPEND(Unit, units_by_type, u->manager->units_by_type[t], u);
166
169
if (UNIT_VTABLE(u)->init)
167
170
UNIT_VTABLE(u)->init(u);
259
262
void unit_add_to_load_queue(Unit *u) {
261
assert(u->meta.type != _UNIT_TYPE_INVALID);
264
assert(u->type != _UNIT_TYPE_INVALID);
263
if (u->meta.load_state != UNIT_STUB || u->meta.in_load_queue)
266
if (u->load_state != UNIT_STUB || u->in_load_queue)
266
LIST_PREPEND(Meta, load_queue, u->meta.manager->load_queue, &u->meta);
267
u->meta.in_load_queue = true;
269
LIST_PREPEND(Unit, load_queue, u->manager->load_queue, u);
270
u->in_load_queue = true;
270
273
void unit_add_to_cleanup_queue(Unit *u) {
273
if (u->meta.in_cleanup_queue)
276
if (u->in_cleanup_queue)
276
LIST_PREPEND(Meta, cleanup_queue, u->meta.manager->cleanup_queue, &u->meta);
277
u->meta.in_cleanup_queue = true;
279
LIST_PREPEND(Unit, cleanup_queue, u->manager->cleanup_queue, u);
280
u->in_cleanup_queue = true;
280
283
void unit_add_to_gc_queue(Unit *u) {
283
if (u->meta.in_gc_queue || u->meta.in_cleanup_queue)
286
if (u->in_gc_queue || u->in_cleanup_queue)
286
289
if (unit_check_gc(u))
289
LIST_PREPEND(Meta, gc_queue, u->meta.manager->gc_queue, &u->meta);
290
u->meta.in_gc_queue = true;
292
u->meta.manager->n_in_gc_queue ++;
294
if (u->meta.manager->gc_queue_timestamp <= 0)
295
u->meta.manager->gc_queue_timestamp = now(CLOCK_MONOTONIC);
292
LIST_PREPEND(Unit, gc_queue, u->manager->gc_queue, u);
293
u->in_gc_queue = true;
295
u->manager->n_in_gc_queue ++;
297
if (u->manager->gc_queue_timestamp <= 0)
298
u->manager->gc_queue_timestamp = now(CLOCK_MONOTONIC);
298
301
void unit_add_to_dbus_queue(Unit *u) {
300
assert(u->meta.type != _UNIT_TYPE_INVALID);
303
assert(u->type != _UNIT_TYPE_INVALID);
302
if (u->meta.load_state == UNIT_STUB || u->meta.in_dbus_queue)
305
if (u->load_state == UNIT_STUB || u->in_dbus_queue)
305
308
/* Shortcut things if nobody cares */
306
if (!bus_has_subscriber(u->meta.manager)) {
307
u->meta.sent_dbus_new_signal = true;
309
if (!bus_has_subscriber(u->manager)) {
310
u->sent_dbus_new_signal = true;
311
LIST_PREPEND(Meta, dbus_queue, u->meta.manager->dbus_unit_queue, &u->meta);
312
u->meta.in_dbus_queue = true;
314
LIST_PREPEND(Unit, dbus_queue, u->manager->dbus_unit_queue, u);
315
u->in_dbus_queue = true;
315
318
static void bidi_set_free(Unit *u, Set *s) {
343
346
bus_unit_send_removed_signal(u);
345
if (u->meta.load_state != UNIT_STUB)
348
if (u->load_state != UNIT_STUB)
346
349
if (UNIT_VTABLE(u)->done)
347
350
UNIT_VTABLE(u)->done(u);
349
SET_FOREACH(t, u->meta.names, i)
350
hashmap_remove_value(u->meta.manager->units, t, u);
352
SET_FOREACH(t, u->names, i)
353
hashmap_remove_value(u->manager->units, t, u);
353
job_free(u->meta.job);
355
358
for (d = 0; d < _UNIT_DEPENDENCY_MAX; d++)
356
bidi_set_free(u, u->meta.dependencies[d]);
358
if (u->meta.type != _UNIT_TYPE_INVALID)
359
LIST_REMOVE(Meta, units_by_type, u->meta.manager->units_by_type[u->meta.type], &u->meta);
361
if (u->meta.in_load_queue)
362
LIST_REMOVE(Meta, load_queue, u->meta.manager->load_queue, &u->meta);
364
if (u->meta.in_dbus_queue)
365
LIST_REMOVE(Meta, dbus_queue, u->meta.manager->dbus_unit_queue, &u->meta);
367
if (u->meta.in_cleanup_queue)
368
LIST_REMOVE(Meta, cleanup_queue, u->meta.manager->cleanup_queue, &u->meta);
370
if (u->meta.in_gc_queue) {
371
LIST_REMOVE(Meta, gc_queue, u->meta.manager->gc_queue, &u->meta);
372
u->meta.manager->n_in_gc_queue--;
359
bidi_set_free(u, u->dependencies[d]);
361
if (u->type != _UNIT_TYPE_INVALID)
362
LIST_REMOVE(Unit, units_by_type, u->manager->units_by_type[u->type], u);
364
if (u->in_load_queue)
365
LIST_REMOVE(Unit, load_queue, u->manager->load_queue, u);
367
if (u->in_dbus_queue)
368
LIST_REMOVE(Unit, dbus_queue, u->manager->dbus_unit_queue, u);
370
if (u->in_cleanup_queue)
371
LIST_REMOVE(Unit, cleanup_queue, u->manager->cleanup_queue, u);
373
if (u->in_gc_queue) {
374
LIST_REMOVE(Unit, gc_queue, u->manager->gc_queue, u);
375
u->manager->n_in_gc_queue--;
375
cgroup_bonding_free_list(u->meta.cgroup_bondings, u->meta.manager->n_reloading <= 0);
376
cgroup_attribute_free_list(u->meta.cgroup_attributes);
378
free(u->meta.description);
379
free(u->meta.fragment_path);
381
set_free_free(u->meta.names);
383
condition_free_list(u->meta.conditions);
385
free(u->meta.instance);
378
cgroup_bonding_free_list(u->cgroup_bondings, u->manager->n_reloading <= 0);
379
cgroup_attribute_free_list(u->cgroup_attributes);
381
free(u->description);
382
free(u->fragment_path);
385
set_free_free(u->names);
387
condition_free_list(u->conditions);
390
unit_ref_unset(u->refs);
389
395
UnitActiveState unit_active_state(Unit *u) {
392
if (u->meta.load_state == UNIT_MERGED)
398
if (u->load_state == UNIT_MERGED)
393
399
return unit_active_state(unit_follow_merge(u));
395
401
/* After a reload it might happen that a unit is not correctly
447
453
assert(d < _UNIT_DEPENDENCY_MAX);
449
455
/* Fix backwards pointers */
450
SET_FOREACH(back, other->meta.dependencies[d], i) {
456
SET_FOREACH(back, other->dependencies[d], i) {
451
457
UnitDependency k;
453
459
for (k = 0; k < _UNIT_DEPENDENCY_MAX; k++)
454
if ((r = set_remove_and_put(back->meta.dependencies[k], other, u)) < 0) {
460
if ((r = set_remove_and_put(back->dependencies[k], other, u)) < 0) {
456
462
if (r == -EEXIST)
457
set_remove(back->meta.dependencies[k], other);
463
set_remove(back->dependencies[k], other);
459
465
assert(r == -ENOENT);
463
complete_move(&u->meta.dependencies[d], &other->meta.dependencies[d]);
469
complete_move(&u->dependencies[d], &other->dependencies[d]);
465
set_free(other->meta.dependencies[d]);
466
other->meta.dependencies[d] = NULL;
471
set_free(other->dependencies[d]);
472
other->dependencies[d] = NULL;
469
475
int unit_merge(Unit *u, Unit *other) {
562
572
if (c->std_output != EXEC_OUTPUT_KMSG &&
563
573
c->std_output != EXEC_OUTPUT_SYSLOG &&
574
c->std_output != EXEC_OUTPUT_JOURNAL &&
564
575
c->std_output != EXEC_OUTPUT_KMSG_AND_CONSOLE &&
565
576
c->std_output != EXEC_OUTPUT_SYSLOG_AND_CONSOLE &&
566
c->std_error != EXEC_OUTPUT_KMSG &&
567
c->std_error != EXEC_OUTPUT_SYSLOG_AND_CONSOLE &&
568
c->std_error != EXEC_OUTPUT_KMSG &&
577
c->std_output != EXEC_OUTPUT_JOURNAL_AND_CONSOLE &&
578
c->std_error != EXEC_OUTPUT_KMSG &&
579
c->std_error != EXEC_OUTPUT_SYSLOG &&
580
c->std_error != EXEC_OUTPUT_JOURNAL &&
581
c->std_error != EXEC_OUTPUT_KMSG_AND_CONSOLE &&
582
c->std_error != EXEC_OUTPUT_JOURNAL_AND_CONSOLE &&
569
583
c->std_error != EXEC_OUTPUT_SYSLOG_AND_CONSOLE)
572
586
/* If syslog or kernel logging is requested, make sure our own
573
587
* logging daemon is run first. */
575
if (u->meta.manager->running_as == MANAGER_SYSTEM)
576
if ((r = unit_add_two_dependencies_by_name(u, UNIT_REQUIRES, UNIT_AFTER, SPECIAL_STDOUT_SYSLOG_BRIDGE_SOCKET, NULL, true)) < 0)
589
if (u->manager->running_as == MANAGER_SYSTEM)
590
if ((r = unit_add_two_dependencies_by_name(u, UNIT_REQUIRES, UNIT_AFTER, SPECIAL_JOURNALD_SOCKET, NULL, true)) < 0)
622
636
"%s\tInactive Enter Timestamp: %s\n"
623
637
"%s\tGC Check Good: %s\n"
624
638
"%s\tNeed Daemon Reload: %s\n",
626
640
prefix, unit_description(u),
627
prefix, strna(u->meta.instance),
628
prefix, unit_load_state_to_string(u->meta.load_state),
641
prefix, strna(u->instance),
642
prefix, unit_load_state_to_string(u->load_state),
629
643
prefix, unit_active_state_to_string(unit_active_state(u)),
630
prefix, strna(format_timestamp(timestamp1, sizeof(timestamp1), u->meta.inactive_exit_timestamp.realtime)),
631
prefix, strna(format_timestamp(timestamp2, sizeof(timestamp2), u->meta.active_enter_timestamp.realtime)),
632
prefix, strna(format_timestamp(timestamp3, sizeof(timestamp3), u->meta.active_exit_timestamp.realtime)),
633
prefix, strna(format_timestamp(timestamp4, sizeof(timestamp4), u->meta.inactive_enter_timestamp.realtime)),
644
prefix, strna(format_timestamp(timestamp1, sizeof(timestamp1), u->inactive_exit_timestamp.realtime)),
645
prefix, strna(format_timestamp(timestamp2, sizeof(timestamp2), u->active_enter_timestamp.realtime)),
646
prefix, strna(format_timestamp(timestamp3, sizeof(timestamp3), u->active_exit_timestamp.realtime)),
647
prefix, strna(format_timestamp(timestamp4, sizeof(timestamp4), u->inactive_enter_timestamp.realtime)),
634
648
prefix, yes_no(unit_check_gc(u)),
635
649
prefix, yes_no(unit_need_daemon_reload(u)));
637
SET_FOREACH(t, u->meta.names, i)
651
SET_FOREACH(t, u->names, i)
638
652
fprintf(f, "%s\tName: %s\n", prefix, t);
640
654
if ((following = unit_following(u)))
641
fprintf(f, "%s\tFollowing: %s\n", prefix, following->meta.id);
643
if (u->meta.fragment_path)
644
fprintf(f, "%s\tFragment Path: %s\n", prefix, u->meta.fragment_path);
646
if (u->meta.job_timeout > 0)
647
fprintf(f, "%s\tJob Timeout: %s\n", prefix, format_timespan(timespan, sizeof(timespan), u->meta.job_timeout));
649
condition_dump_list(u->meta.conditions, f, prefix);
651
if (dual_timestamp_is_set(&u->meta.condition_timestamp))
655
fprintf(f, "%s\tFollowing: %s\n", prefix, following->id);
657
if (u->fragment_path)
658
fprintf(f, "%s\tFragment Path: %s\n", prefix, u->fragment_path);
660
if (u->job_timeout > 0)
661
fprintf(f, "%s\tJob Timeout: %s\n", prefix, format_timespan(timespan, sizeof(timespan), u->job_timeout));
663
condition_dump_list(u->conditions, f, prefix);
665
if (dual_timestamp_is_set(&u->condition_timestamp))
653
667
"%s\tCondition Timestamp: %s\n"
654
668
"%s\tCondition Result: %s\n",
655
prefix, strna(format_timestamp(timestamp1, sizeof(timestamp1), u->meta.condition_timestamp.realtime)),
656
prefix, yes_no(u->meta.condition_result));
669
prefix, strna(format_timestamp(timestamp1, sizeof(timestamp1), u->condition_timestamp.realtime)),
670
prefix, yes_no(u->condition_result));
658
672
for (d = 0; d < _UNIT_DEPENDENCY_MAX; d++) {
661
SET_FOREACH(other, u->meta.dependencies[d], i)
662
fprintf(f, "%s\t%s: %s\n", prefix, unit_dependency_to_string(d), other->meta.id);
675
SET_FOREACH(other, u->dependencies[d], i)
676
fprintf(f, "%s\t%s: %s\n", prefix, unit_dependency_to_string(d), other->id);
665
if (u->meta.load_state == UNIT_LOADED) {
679
if (u->load_state == UNIT_LOADED) {
666
680
CGroupBonding *b;
667
681
CGroupAttribute *a;
674
688
"%s\tOnFailureIsolate: %s\n"
675
689
"%s\tIgnoreOnIsolate: %s\n"
676
690
"%s\tIgnoreOnSnapshot: %s\n",
677
prefix, yes_no(u->meta.stop_when_unneeded),
678
prefix, yes_no(u->meta.refuse_manual_start),
679
prefix, yes_no(u->meta.refuse_manual_stop),
680
prefix, yes_no(u->meta.default_dependencies),
681
prefix, yes_no(u->meta.on_failure_isolate),
682
prefix, yes_no(u->meta.ignore_on_isolate),
683
prefix, yes_no(u->meta.ignore_on_snapshot));
691
prefix, yes_no(u->stop_when_unneeded),
692
prefix, yes_no(u->refuse_manual_start),
693
prefix, yes_no(u->refuse_manual_stop),
694
prefix, yes_no(u->default_dependencies),
695
prefix, yes_no(u->on_failure_isolate),
696
prefix, yes_no(u->ignore_on_isolate),
697
prefix, yes_no(u->ignore_on_snapshot));
685
LIST_FOREACH(by_unit, b, u->meta.cgroup_bondings)
699
LIST_FOREACH(by_unit, b, u->cgroup_bondings)
686
700
fprintf(f, "%s\tControlGroup: %s:%s\n",
687
701
prefix, b->controller, b->path);
689
LIST_FOREACH(by_unit, a, u->meta.cgroup_attributes) {
703
LIST_FOREACH(by_unit, a, u->cgroup_attributes) {
692
706
if (a->map_callback)
765
if (target->meta.type != UNIT_TARGET)
779
if (target->type != UNIT_TARGET)
768
782
/* Only add the dependency if both units are loaded, so that
769
783
* that loop check below is reliable */
770
if (u->meta.load_state != UNIT_LOADED ||
771
target->meta.load_state != UNIT_LOADED)
784
if (u->load_state != UNIT_LOADED ||
785
target->load_state != UNIT_LOADED)
774
788
/* If either side wants no automatic dependencies, then let's
776
if (!u->meta.default_dependencies ||
777
!target->meta.default_dependencies)
790
if (!u->default_dependencies ||
791
!target->default_dependencies)
780
794
/* Don't create loops */
781
if (set_get(target->meta.dependencies[UNIT_BEFORE], u))
795
if (set_get(target->dependencies[UNIT_BEFORE], u))
784
798
return unit_add_dependency(target, UNIT_AFTER, u, true);
815
if (u->meta.in_load_queue) {
816
LIST_REMOVE(Meta, load_queue, u->meta.manager->load_queue, &u->meta);
817
u->meta.in_load_queue = false;
829
if (u->in_load_queue) {
830
LIST_REMOVE(Unit, load_queue, u->manager->load_queue, u);
831
u->in_load_queue = false;
820
if (u->meta.type == _UNIT_TYPE_INVALID)
834
if (u->type == _UNIT_TYPE_INVALID)
823
if (u->meta.load_state != UNIT_STUB)
837
if (u->load_state != UNIT_STUB)
826
840
if (UNIT_VTABLE(u)->load)
827
841
if ((r = UNIT_VTABLE(u)->load(u)) < 0)
830
if (u->meta.load_state == UNIT_STUB) {
844
if (u->load_state == UNIT_STUB) {
835
if (u->meta.load_state == UNIT_LOADED &&
836
u->meta.default_dependencies)
849
if (u->load_state == UNIT_LOADED &&
850
u->default_dependencies)
837
851
if ((r = unit_add_default_dependencies(u)) < 0)
840
if (u->meta.on_failure_isolate &&
841
set_size(u->meta.dependencies[UNIT_ON_FAILURE]) > 1) {
854
if (u->on_failure_isolate &&
855
set_size(u->dependencies[UNIT_ON_FAILURE]) > 1) {
843
857
log_error("More than one OnFailure= dependencies specified for %s but OnFailureIsolate= enabled. Refusing.",
850
assert((u->meta.load_state != UNIT_MERGED) == !u->meta.merged_into);
864
assert((u->load_state != UNIT_MERGED) == !u->merged_into);
852
866
unit_add_to_dbus_queue(unit_follow_merge(u));
853
867
unit_add_to_gc_queue(u);
1024
1039
/* If this service shall be shut down when unneeded then do
1027
if (!u->meta.stop_when_unneeded)
1042
if (!u->stop_when_unneeded)
1030
1045
if (!UNIT_IS_ACTIVE_OR_ACTIVATING(unit_active_state(u)))
1033
SET_FOREACH(other, u->meta.dependencies[UNIT_REQUIRED_BY], i)
1034
if (!UNIT_IS_INACTIVE_OR_DEACTIVATING(unit_active_state(other)))
1037
SET_FOREACH(other, u->meta.dependencies[UNIT_REQUIRED_BY_OVERRIDABLE], i)
1038
if (!UNIT_IS_INACTIVE_OR_DEACTIVATING(unit_active_state(other)))
1041
SET_FOREACH(other, u->meta.dependencies[UNIT_WANTED_BY], i)
1042
if (!UNIT_IS_INACTIVE_OR_DEACTIVATING(unit_active_state(other)))
1045
SET_FOREACH(other, u->meta.dependencies[UNIT_BOUND_BY], i)
1046
if (!UNIT_IS_INACTIVE_OR_DEACTIVATING(unit_active_state(other)))
1049
log_info("Service %s is not needed anymore. Stopping.", u->meta.id);
1048
SET_FOREACH(other, u->dependencies[UNIT_REQUIRED_BY], i)
1049
if (unit_pending_active(other))
1052
SET_FOREACH(other, u->dependencies[UNIT_REQUIRED_BY_OVERRIDABLE], i)
1053
if (unit_pending_active(other))
1056
SET_FOREACH(other, u->dependencies[UNIT_WANTED_BY], i)
1057
if (unit_pending_active(other))
1060
SET_FOREACH(other, u->dependencies[UNIT_BOUND_BY], i)
1061
if (unit_pending_active(other))
1064
log_info("Service %s is not needed anymore. Stopping.", u->id);
1051
1066
/* Ok, nobody needs us anymore. Sniff. Then let's commit suicide */
1052
manager_add_job(u->meta.manager, JOB_STOP, u, JOB_FAIL, true, NULL, NULL);
1067
manager_add_job(u->manager, JOB_STOP, u, JOB_FAIL, true, NULL, NULL);
1055
1070
static void retroactively_start_dependencies(Unit *u) {
1060
1075
assert(UNIT_IS_ACTIVE_OR_ACTIVATING(unit_active_state(u)));
1062
SET_FOREACH(other, u->meta.dependencies[UNIT_REQUIRES], i)
1063
if (!set_get(u->meta.dependencies[UNIT_AFTER], other) &&
1064
!UNIT_IS_ACTIVE_OR_ACTIVATING(unit_active_state(other)))
1065
manager_add_job(u->meta.manager, JOB_START, other, JOB_REPLACE, true, NULL, NULL);
1067
SET_FOREACH(other, u->meta.dependencies[UNIT_BIND_TO], i)
1068
if (!set_get(u->meta.dependencies[UNIT_AFTER], other) &&
1069
!UNIT_IS_ACTIVE_OR_ACTIVATING(unit_active_state(other)))
1070
manager_add_job(u->meta.manager, JOB_START, other, JOB_REPLACE, true, NULL, NULL);
1072
SET_FOREACH(other, u->meta.dependencies[UNIT_REQUIRES_OVERRIDABLE], i)
1073
if (!set_get(u->meta.dependencies[UNIT_AFTER], other) &&
1074
!UNIT_IS_ACTIVE_OR_ACTIVATING(unit_active_state(other)))
1075
manager_add_job(u->meta.manager, JOB_START, other, JOB_FAIL, false, NULL, NULL);
1077
SET_FOREACH(other, u->meta.dependencies[UNIT_REQUISITE], i)
1078
if (!set_get(u->meta.dependencies[UNIT_AFTER], other) &&
1079
!UNIT_IS_ACTIVE_OR_ACTIVATING(unit_active_state(other)))
1080
manager_add_job(u->meta.manager, JOB_START, other, JOB_REPLACE, true, NULL, NULL);
1082
SET_FOREACH(other, u->meta.dependencies[UNIT_WANTS], i)
1083
if (!set_get(u->meta.dependencies[UNIT_AFTER], other) &&
1084
!UNIT_IS_ACTIVE_OR_ACTIVATING(unit_active_state(other)))
1085
manager_add_job(u->meta.manager, JOB_START, other, JOB_FAIL, false, NULL, NULL);
1087
SET_FOREACH(other, u->meta.dependencies[UNIT_CONFLICTS], i)
1088
if (!UNIT_IS_INACTIVE_OR_DEACTIVATING(unit_active_state(other)))
1089
manager_add_job(u->meta.manager, JOB_STOP, other, JOB_REPLACE, true, NULL, NULL);
1091
SET_FOREACH(other, u->meta.dependencies[UNIT_CONFLICTED_BY], i)
1092
if (!UNIT_IS_INACTIVE_OR_DEACTIVATING(unit_active_state(other)))
1093
manager_add_job(u->meta.manager, JOB_STOP, other, JOB_REPLACE, true, NULL, NULL);
1077
SET_FOREACH(other, u->dependencies[UNIT_REQUIRES], i)
1078
if (!set_get(u->dependencies[UNIT_AFTER], other) &&
1079
!UNIT_IS_ACTIVE_OR_ACTIVATING(unit_active_state(other)))
1080
manager_add_job(u->manager, JOB_START, other, JOB_REPLACE, true, NULL, NULL);
1082
SET_FOREACH(other, u->dependencies[UNIT_BIND_TO], i)
1083
if (!set_get(u->dependencies[UNIT_AFTER], other) &&
1084
!UNIT_IS_ACTIVE_OR_ACTIVATING(unit_active_state(other)))
1085
manager_add_job(u->manager, JOB_START, other, JOB_REPLACE, true, NULL, NULL);
1087
SET_FOREACH(other, u->dependencies[UNIT_REQUIRES_OVERRIDABLE], i)
1088
if (!set_get(u->dependencies[UNIT_AFTER], other) &&
1089
!UNIT_IS_ACTIVE_OR_ACTIVATING(unit_active_state(other)))
1090
manager_add_job(u->manager, JOB_START, other, JOB_FAIL, false, NULL, NULL);
1092
SET_FOREACH(other, u->dependencies[UNIT_REQUISITE], i)
1093
if (!set_get(u->dependencies[UNIT_AFTER], other) &&
1094
!UNIT_IS_ACTIVE_OR_ACTIVATING(unit_active_state(other)))
1095
manager_add_job(u->manager, JOB_START, other, JOB_REPLACE, true, NULL, NULL);
1097
SET_FOREACH(other, u->dependencies[UNIT_WANTS], i)
1098
if (!set_get(u->dependencies[UNIT_AFTER], other) &&
1099
!UNIT_IS_ACTIVE_OR_ACTIVATING(unit_active_state(other)))
1100
manager_add_job(u->manager, JOB_START, other, JOB_FAIL, false, NULL, NULL);
1102
SET_FOREACH(other, u->dependencies[UNIT_CONFLICTS], i)
1103
if (!UNIT_IS_INACTIVE_OR_DEACTIVATING(unit_active_state(other)))
1104
manager_add_job(u->manager, JOB_STOP, other, JOB_REPLACE, true, NULL, NULL);
1106
SET_FOREACH(other, u->dependencies[UNIT_CONFLICTED_BY], i)
1107
if (!UNIT_IS_INACTIVE_OR_DEACTIVATING(unit_active_state(other)))
1108
manager_add_job(u->manager, JOB_STOP, other, JOB_REPLACE, true, NULL, NULL);
1096
1111
static void retroactively_stop_dependencies(Unit *u) {
1101
1116
assert(UNIT_IS_INACTIVE_OR_DEACTIVATING(unit_active_state(u)));
1103
1118
/* Pull down units which are bound to us recursively if enabled */
1104
SET_FOREACH(other, u->meta.dependencies[UNIT_BOUND_BY], i)
1119
SET_FOREACH(other, u->dependencies[UNIT_BOUND_BY], i)
1105
1120
if (!UNIT_IS_INACTIVE_OR_DEACTIVATING(unit_active_state(other)))
1106
manager_add_job(u->meta.manager, JOB_STOP, other, JOB_REPLACE, true, NULL, NULL);
1121
manager_add_job(u->manager, JOB_STOP, other, JOB_REPLACE, true, NULL, NULL);
1124
static void check_unneeded_dependencies(Unit *u) {
1129
assert(UNIT_IS_INACTIVE_OR_DEACTIVATING(unit_active_state(u)));
1108
1131
/* Garbage collect services that might not be needed anymore, if enabled */
1109
SET_FOREACH(other, u->meta.dependencies[UNIT_REQUIRES], i)
1110
if (!UNIT_IS_INACTIVE_OR_DEACTIVATING(unit_active_state(other)))
1111
unit_check_unneeded(other);
1112
SET_FOREACH(other, u->meta.dependencies[UNIT_REQUIRES_OVERRIDABLE], i)
1113
if (!UNIT_IS_INACTIVE_OR_DEACTIVATING(unit_active_state(other)))
1114
unit_check_unneeded(other);
1115
SET_FOREACH(other, u->meta.dependencies[UNIT_WANTS], i)
1116
if (!UNIT_IS_INACTIVE_OR_DEACTIVATING(unit_active_state(other)))
1117
unit_check_unneeded(other);
1118
SET_FOREACH(other, u->meta.dependencies[UNIT_REQUISITE], i)
1119
if (!UNIT_IS_INACTIVE_OR_DEACTIVATING(unit_active_state(other)))
1120
unit_check_unneeded(other);
1121
SET_FOREACH(other, u->meta.dependencies[UNIT_REQUISITE_OVERRIDABLE], i)
1122
if (!UNIT_IS_INACTIVE_OR_DEACTIVATING(unit_active_state(other)))
1123
unit_check_unneeded(other);
1124
SET_FOREACH(other, u->meta.dependencies[UNIT_BIND_TO], i)
1132
SET_FOREACH(other, u->dependencies[UNIT_REQUIRES], i)
1133
if (!UNIT_IS_INACTIVE_OR_DEACTIVATING(unit_active_state(other)))
1134
unit_check_unneeded(other);
1135
SET_FOREACH(other, u->dependencies[UNIT_REQUIRES_OVERRIDABLE], i)
1136
if (!UNIT_IS_INACTIVE_OR_DEACTIVATING(unit_active_state(other)))
1137
unit_check_unneeded(other);
1138
SET_FOREACH(other, u->dependencies[UNIT_WANTS], i)
1139
if (!UNIT_IS_INACTIVE_OR_DEACTIVATING(unit_active_state(other)))
1140
unit_check_unneeded(other);
1141
SET_FOREACH(other, u->dependencies[UNIT_REQUISITE], i)
1142
if (!UNIT_IS_INACTIVE_OR_DEACTIVATING(unit_active_state(other)))
1143
unit_check_unneeded(other);
1144
SET_FOREACH(other, u->dependencies[UNIT_REQUISITE_OVERRIDABLE], i)
1145
if (!UNIT_IS_INACTIVE_OR_DEACTIVATING(unit_active_state(other)))
1146
unit_check_unneeded(other);
1147
SET_FOREACH(other, u->dependencies[UNIT_BIND_TO], i)
1125
1148
if (!UNIT_IS_INACTIVE_OR_DEACTIVATING(unit_active_state(other)))
1126
1149
unit_check_unneeded(other);
1158
1181
* behaviour here. For example: if a mount point is remounted
1159
1182
* this function will be called too! */
1161
if (u->meta.manager->n_reloading <= 0) {
1184
if (u->manager->n_reloading <= 0) {
1162
1185
dual_timestamp ts;
1164
1187
dual_timestamp_get(&ts);
1166
1189
if (UNIT_IS_INACTIVE_OR_FAILED(os) && !UNIT_IS_INACTIVE_OR_FAILED(ns))
1167
u->meta.inactive_exit_timestamp = ts;
1190
u->inactive_exit_timestamp = ts;
1168
1191
else if (!UNIT_IS_INACTIVE_OR_FAILED(os) && UNIT_IS_INACTIVE_OR_FAILED(ns))
1169
u->meta.inactive_enter_timestamp = ts;
1192
u->inactive_enter_timestamp = ts;
1171
1194
if (!UNIT_IS_ACTIVE_OR_RELOADING(os) && UNIT_IS_ACTIVE_OR_RELOADING(ns))
1172
u->meta.active_enter_timestamp = ts;
1195
u->active_enter_timestamp = ts;
1173
1196
else if (UNIT_IS_ACTIVE_OR_RELOADING(os) && !UNIT_IS_ACTIVE_OR_RELOADING(ns))
1174
u->meta.active_exit_timestamp = ts;
1197
u->active_exit_timestamp = ts;
1176
1199
timer_unit_notify(u, ns);
1177
1200
path_unit_notify(u, ns);
1180
1203
if (UNIT_IS_INACTIVE_OR_FAILED(ns))
1181
cgroup_bonding_trim_list(u->meta.cgroup_bondings, true);
1204
cgroup_bonding_trim_list(u->cgroup_bondings, true);
1184
1207
unexpected = false;
1186
if (u->meta.job->state == JOB_WAITING)
1209
if (u->job->state == JOB_WAITING)
1188
1211
/* So we reached a different state for this
1189
1212
* job. Let's see if we can run it now if it
1190
1213
* failed previously due to EAGAIN. */
1191
job_add_to_run_queue(u->meta.job);
1214
job_add_to_run_queue(u->job);
1193
1216
/* Let's check whether this state change constitutes a
1194
1217
* finished job, or maybe contradicts a running job and
1195
1218
* hence needs to invalidate jobs. */
1197
switch (u->meta.job->type) {
1220
switch (u->job->type) {
1199
1222
case JOB_START:
1200
1223
case JOB_VERIFY_ACTIVE:
1202
1225
if (UNIT_IS_ACTIVE_OR_RELOADING(ns))
1203
job_finish_and_invalidate(u->meta.job, JOB_DONE);
1204
else if (u->meta.job->state == JOB_RUNNING && ns != UNIT_ACTIVATING) {
1226
job_finish_and_invalidate(u->job, JOB_DONE);
1227
else if (u->job->state == JOB_RUNNING && ns != UNIT_ACTIVATING) {
1205
1228
unexpected = true;
1207
1230
if (UNIT_IS_INACTIVE_OR_FAILED(ns))
1208
job_finish_and_invalidate(u->meta.job, ns == UNIT_FAILED ? JOB_FAILED : JOB_DONE);
1231
job_finish_and_invalidate(u->job, ns == UNIT_FAILED ? JOB_FAILED : JOB_DONE);
1275
1302
/* The bus just might have become available,
1276
1303
* hence try to connect to it, if we aren't
1277
1304
* yet connected. */
1278
bus_init(u->meta.manager, true);
1305
bus_init(u->manager, true);
1280
if (u->meta.type == UNIT_SERVICE &&
1307
if (u->type == UNIT_SERVICE &&
1281
1308
!UNIT_IS_ACTIVE_OR_RELOADING(os) &&
1282
u->meta.manager->n_reloading <= 0) {
1309
u->manager->n_reloading <= 0) {
1283
1310
/* Write audit record if we have just finished starting up */
1284
manager_send_unit_audit(u->meta.manager, u, AUDIT_SERVICE_START, true);
1285
u->meta.in_audit = true;
1311
manager_send_unit_audit(u->manager, u, AUDIT_SERVICE_START, true);
1288
1315
if (!UNIT_IS_ACTIVE_OR_RELOADING(os))
1289
manager_send_unit_plymouth(u->meta.manager, u);
1316
manager_send_unit_plymouth(u->manager, u);
1293
1320
/* We don't care about D-Bus here, since we'll get an
1294
1321
* asynchronous notification for it anyway. */
1296
if (u->meta.type == UNIT_SERVICE &&
1323
if (u->type == UNIT_SERVICE &&
1297
1324
UNIT_IS_INACTIVE_OR_FAILED(ns) &&
1298
1325
!UNIT_IS_INACTIVE_OR_FAILED(os) &&
1299
u->meta.manager->n_reloading <= 0) {
1326
u->manager->n_reloading <= 0) {
1301
1328
/* Hmm, if there was no start record written
1302
1329
* write it now, so that we always have a nice
1304
if (!u->meta.in_audit) {
1305
manager_send_unit_audit(u->meta.manager, u, AUDIT_SERVICE_START, ns == UNIT_INACTIVE);
1332
manager_send_unit_audit(u->manager, u, AUDIT_SERVICE_START, ns == UNIT_INACTIVE);
1307
1334
if (ns == UNIT_INACTIVE)
1308
manager_send_unit_audit(u->meta.manager, u, AUDIT_SERVICE_STOP, true);
1335
manager_send_unit_audit(u->manager, u, AUDIT_SERVICE_STOP, true);
1310
1337
/* Write audit record if we have just finished shutting down */
1311
manager_send_unit_audit(u->meta.manager, u, AUDIT_SERVICE_STOP, ns == UNIT_INACTIVE);
1338
manager_send_unit_audit(u->manager, u, AUDIT_SERVICE_STOP, ns == UNIT_INACTIVE);
1313
u->meta.in_audit = false;
1340
u->in_audit = false;
1317
manager_recheck_syslog(u->meta.manager);
1344
manager_recheck_journal(u->manager);
1319
1346
/* Maybe we finished startup and are now ready for being
1320
1347
* stopped because unneeded? */
1529
1560
if (u == other)
1532
if ((r = set_ensure_allocated(&u->meta.dependencies[d], trivial_hash_func, trivial_compare_func)) < 0)
1563
if ((r = set_ensure_allocated(&u->dependencies[d], trivial_hash_func, trivial_compare_func)) < 0)
1535
1566
if (inverse_table[d] != _UNIT_DEPENDENCY_INVALID)
1536
if ((r = set_ensure_allocated(&other->meta.dependencies[inverse_table[d]], trivial_hash_func, trivial_compare_func)) < 0)
1567
if ((r = set_ensure_allocated(&other->dependencies[inverse_table[d]], trivial_hash_func, trivial_compare_func)) < 0)
1539
1570
if (add_reference)
1540
if ((r = set_ensure_allocated(&u->meta.dependencies[UNIT_REFERENCES], trivial_hash_func, trivial_compare_func)) < 0 ||
1541
(r = set_ensure_allocated(&other->meta.dependencies[UNIT_REFERENCED_BY], trivial_hash_func, trivial_compare_func)) < 0)
1571
if ((r = set_ensure_allocated(&u->dependencies[UNIT_REFERENCES], trivial_hash_func, trivial_compare_func)) < 0 ||
1572
(r = set_ensure_allocated(&other->dependencies[UNIT_REFERENCED_BY], trivial_hash_func, trivial_compare_func)) < 0)
1544
if ((q = set_put(u->meta.dependencies[d], other)) < 0)
1575
if ((q = set_put(u->dependencies[d], other)) < 0)
1547
1578
if (inverse_table[d] != _UNIT_DEPENDENCY_INVALID)
1548
if ((v = set_put(other->meta.dependencies[inverse_table[d]], u)) < 0) {
1579
if ((v = set_put(other->dependencies[inverse_table[d]], u)) < 0) {
1553
1584
if (add_reference) {
1554
if ((w = set_put(u->meta.dependencies[UNIT_REFERENCES], other)) < 0) {
1585
if ((w = set_put(u->dependencies[UNIT_REFERENCES], other)) < 0) {
1559
if ((r = set_put(other->meta.dependencies[UNIT_REFERENCED_BY], u)) < 0)
1590
if ((r = set_put(other->dependencies[UNIT_REFERENCED_BY], u)) < 0)
2172
2203
const Specifier table[] = {
2173
{ 'n', specifier_string, u->meta.id },
2204
{ 'n', specifier_string, u->id },
2174
2205
{ 'N', specifier_prefix_and_instance, NULL },
2175
2206
{ 'p', specifier_prefix, NULL },
2176
2207
{ 'P', specifier_prefix_unescaped, NULL },
2177
{ 'i', specifier_string, u->meta.instance },
2208
{ 'i', specifier_string, u->instance },
2178
2209
{ 'I', specifier_instance_unescaped, NULL },
2179
2210
{ 'f', specifier_filename, NULL },
2180
2211
{ 'c', specifier_cgroup, NULL },
2254
2285
if ((r = UNIT_VTABLE(u)->serialize(u, f, fds)) < 0)
2258
unit_serialize_item(u, f, "job", job_type_to_string(u->meta.job->type));
2260
dual_timestamp_serialize(f, "inactive-exit-timestamp", &u->meta.inactive_exit_timestamp);
2261
dual_timestamp_serialize(f, "active-enter-timestamp", &u->meta.active_enter_timestamp);
2262
dual_timestamp_serialize(f, "active-exit-timestamp", &u->meta.active_exit_timestamp);
2263
dual_timestamp_serialize(f, "inactive-enter-timestamp", &u->meta.inactive_enter_timestamp);
2264
dual_timestamp_serialize(f, "condition-timestamp", &u->meta.condition_timestamp);
2266
if (dual_timestamp_is_set(&u->meta.condition_timestamp))
2267
unit_serialize_item(u, f, "condition-result", yes_no(u->meta.condition_result));
2289
unit_serialize_item(u, f, "job", job_type_to_string(u->job->type));
2291
dual_timestamp_serialize(f, "inactive-exit-timestamp", &u->inactive_exit_timestamp);
2292
dual_timestamp_serialize(f, "active-enter-timestamp", &u->active_enter_timestamp);
2293
dual_timestamp_serialize(f, "active-exit-timestamp", &u->active_exit_timestamp);
2294
dual_timestamp_serialize(f, "inactive-enter-timestamp", &u->inactive_enter_timestamp);
2295
dual_timestamp_serialize(f, "condition-timestamp", &u->condition_timestamp);
2297
if (dual_timestamp_is_set(&u->condition_timestamp))
2298
unit_serialize_item(u, f, "condition-result", yes_no(u->condition_result));
2269
2300
/* End marker */
2270
2301
fputc('\n', f);
2339
2370
if ((type = job_type_from_string(v)) < 0)
2340
2371
log_debug("Failed to parse job type value %s", v);
2342
u->meta.deserialized_job = type;
2373
u->deserialized_job = type;
2345
2376
} else if (streq(l, "inactive-exit-timestamp")) {
2346
dual_timestamp_deserialize(v, &u->meta.inactive_exit_timestamp);
2377
dual_timestamp_deserialize(v, &u->inactive_exit_timestamp);
2348
2379
} else if (streq(l, "active-enter-timestamp")) {
2349
dual_timestamp_deserialize(v, &u->meta.active_enter_timestamp);
2380
dual_timestamp_deserialize(v, &u->active_enter_timestamp);
2351
2382
} else if (streq(l, "active-exit-timestamp")) {
2352
dual_timestamp_deserialize(v, &u->meta.active_exit_timestamp);
2383
dual_timestamp_deserialize(v, &u->active_exit_timestamp);
2354
2385
} else if (streq(l, "inactive-enter-timestamp")) {
2355
dual_timestamp_deserialize(v, &u->meta.inactive_enter_timestamp);
2386
dual_timestamp_deserialize(v, &u->inactive_enter_timestamp);
2357
2388
} else if (streq(l, "condition-timestamp")) {
2358
dual_timestamp_deserialize(v, &u->meta.condition_timestamp);
2389
dual_timestamp_deserialize(v, &u->condition_timestamp);
2360
2391
} else if (streq(l, "condition-result")) {
2435
2466
if (!UNIT_VTABLE(u)->show_status)
2438
if (!manager_get_show_status(u->meta.manager))
2469
if (!manager_get_show_status(u->manager))
2441
if (!manager_is_booting_or_shutting_down(u->meta.manager))
2472
if (!manager_is_booting_or_shutting_down(u->manager))
2444
2475
va_start(ap, format);
2445
status_vprintf(format, ap);
2476
status_vprintf(status, true, format, ap);
2449
2480
bool unit_need_daemon_reload(Unit *u) {
2452
if (u->meta.fragment_path) {
2483
if (u->fragment_path) {
2453
2484
struct stat st;
2456
if (stat(u->meta.fragment_path, &st) < 0)
2487
if (stat(u->fragment_path, &st) < 0)
2457
2488
/* What, cannot access this anymore? */
2460
if (u->meta.fragment_mtime > 0 &&
2461
timespec_load(&st.st_mtim) != u->meta.fragment_mtime)
2491
if (u->fragment_mtime > 0 &&
2492
timespec_load(&st.st_mtim) != u->fragment_mtime)
2567
2598
UnitFileState unit_get_unit_file_state(Unit *u) {
2570
if (u->meta.unit_file_state < 0 && u->meta.fragment_path)
2571
u->meta.unit_file_state = unit_file_get_state(
2572
u->meta.manager->running_as == MANAGER_SYSTEM ? UNIT_FILE_SYSTEM : UNIT_FILE_USER,
2573
NULL, file_name_from_path(u->meta.fragment_path));
2575
return u->meta.unit_file_state;
2601
if (u->unit_file_state < 0 && u->fragment_path)
2602
u->unit_file_state = unit_file_get_state(
2603
u->manager->running_as == MANAGER_SYSTEM ? UNIT_FILE_SYSTEM : UNIT_FILE_USER,
2604
NULL, file_name_from_path(u->fragment_path));
2606
return u->unit_file_state;
2609
Unit* unit_ref_set(UnitRef *ref, Unit *u) {
2614
unit_ref_unset(ref);
2617
LIST_PREPEND(UnitRef, refs, u->refs, ref);
2621
void unit_ref_unset(UnitRef *ref) {
2627
LIST_REMOVE(UnitRef, refs, ref->unit->refs, ref);
2578
2631
static const char* const unit_load_state_table[_UNIT_LOAD_STATE_MAX] = {