~ubuntu-branches/debian/jessie/systemd/jessie

« back to all changes in this revision

Viewing changes to src/unit.c

  • Committer: Package Import Robot
  • Author(s): Tollef Fog Heen, Tollef Fog Heen, Michael Biebl
  • Date: 2012-04-03 19:59:17 UTC
  • mfrom: (1.1.10) (6.1.3 experimental)
  • Revision ID: package-import@ubuntu.com-20120403195917-l532urrbg4pkreas
Tags: 44-1
[ Tollef Fog Heen ]
* New upstream version.
  - Backport 3492207: journal: PAGE_SIZE is not known on ppc and other
    archs
  - Backport 5a2a2a1: journal: react with immediate rotation to a couple
    of more errors
  - Backport 693ce21: util: never follow symlinks in rm_rf_children()
    Fixes CVE-2012-1174, closes: #664364
* Drop output message from init-functions hook, it's pointless.
* Only rmdir /lib/init/rw if it exists.
* Explicitly order debian-fixup before sysinit.target to prevent a
  possible race condition with the creation of sockets.  Thanks to
  Michael Biebl for debugging this.
* Always restart the initctl socket on upgrades, to mask sysvinit
  removing it.

[ Michael Biebl ]
* Remove workaround for non-interactive sessions from pam config again.
* Create compat /dev/initctl symlink in case we are upgrading from a system
  running a newer version of sysvinit (using /run/initctl) and sysvinit is
  replaced with systemd-sysv during the upgrade. Closes: #663219
* Install new man pages.
* Build-Depend on valac (>= 0.12) instead of valac-0.12. Closes: #663323

Show diffs side-by-side

added added

removed removed

Lines of Context:
57
57
        [UNIT_PATH] = &path_vtable
58
58
};
59
59
 
60
 
Unit *unit_new(Manager *m) {
 
60
Unit *unit_new(Manager *m, size_t size) {
61
61
        Unit *u;
62
62
 
63
63
        assert(m);
 
64
        assert(size >= sizeof(Unit));
64
65
 
65
 
        if (!(u = new0(Unit, 1)))
 
66
        u = malloc0(size);
 
67
        if (!u)
66
68
                return NULL;
67
69
 
68
 
        if (!(u->meta.names = set_new(string_hash_func, string_compare_func))) {
 
70
        u->names = set_new(string_hash_func, string_compare_func);
 
71
        if (!u->names) {
69
72
                free(u);
70
73
                return NULL;
71
74
        }
72
75
 
73
 
        u->meta.manager = m;
74
 
        u->meta.type = _UNIT_TYPE_INVALID;
75
 
        u->meta.deserialized_job = _JOB_TYPE_INVALID;
76
 
        u->meta.default_dependencies = true;
77
 
        u->meta.unit_file_state = _UNIT_FILE_STATE_INVALID;
 
76
        u->manager = m;
 
77
        u->type = _UNIT_TYPE_INVALID;
 
78
        u->deserialized_job = _JOB_TYPE_INVALID;
 
79
        u->default_dependencies = true;
 
80
        u->unit_file_state = _UNIT_FILE_STATE_INVALID;
78
81
 
79
82
        return u;
80
83
}
83
86
        assert(u);
84
87
        assert(name);
85
88
 
86
 
        return !!set_get(u->meta.names, (char*) name);
 
89
        return !!set_get(u->names, (char*) name);
87
90
}
88
91
 
89
92
int unit_add_name(Unit *u, const char *text) {
95
98
        assert(text);
96
99
 
97
100
        if (unit_name_is_template(text)) {
98
 
                if (!u->meta.instance)
 
101
                if (!u->instance)
99
102
                        return -EINVAL;
100
103
 
101
 
                s = unit_name_replace_instance(text, u->meta.instance);
 
104
                s = unit_name_replace_instance(text, u->instance);
102
105
        } else
103
106
                s = strdup(text);
104
107
 
112
115
 
113
116
        assert_se((t = unit_name_to_type(s)) >= 0);
114
117
 
115
 
        if (u->meta.type != _UNIT_TYPE_INVALID && t != u->meta.type) {
 
118
        if (u->type != _UNIT_TYPE_INVALID && t != u->type) {
116
119
                r = -EINVAL;
117
120
                goto fail;
118
121
        }
127
130
 
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) {
131
134
                r = -EINVAL;
132
135
                goto fail;
133
136
        }
134
137
 
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)) {
138
141
                r = -EEXIST;
139
142
                goto fail;
140
143
        }
141
144
 
142
 
        if (hashmap_size(u->meta.manager->units) >= MANAGER_MAX_NAMES) {
 
145
        if (hashmap_size(u->manager->units) >= MANAGER_MAX_NAMES) {
143
146
                r = -E2BIG;
144
147
                goto fail;
145
148
        }
146
149
 
147
 
        if ((r = set_put(u->meta.names, s)) < 0) {
 
150
        if ((r = set_put(u->names, s)) < 0) {
148
151
                if (r == -EEXIST)
149
152
                        r = 0;
150
153
                goto fail;
151
154
        }
152
155
 
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);
155
158
                goto fail;
156
159
        }
157
160
 
158
 
        if (u->meta.type == _UNIT_TYPE_INVALID) {
159
 
 
160
 
                u->meta.type = t;
161
 
                u->meta.id = s;
162
 
                u->meta.instance = i;
163
 
 
164
 
                LIST_PREPEND(Meta, units_by_type, u->meta.manager->units_by_type[t], &u->meta);
 
161
        if (u->type == _UNIT_TYPE_INVALID) {
 
162
 
 
163
                u->type = t;
 
164
                u->id = s;
 
165
                u->instance = i;
 
166
 
 
167
                LIST_PREPEND(Unit, units_by_type, u->manager->units_by_type[t], u);
165
168
 
166
169
                if (UNIT_VTABLE(u)->init)
167
170
                        UNIT_VTABLE(u)->init(u);
187
190
 
188
191
        if (unit_name_is_template(name)) {
189
192
 
190
 
                if (!u->meta.instance)
 
193
                if (!u->instance)
191
194
                        return -EINVAL;
192
195
 
193
 
                if (!(t = unit_name_replace_instance(name, u->meta.instance)))
 
196
                if (!(t = unit_name_replace_instance(name, u->instance)))
194
197
                        return -ENOMEM;
195
198
 
196
199
                name = t;
197
200
        }
198
201
 
199
202
        /* Selects one of the names of this unit as the id */
200
 
        s = set_get(u->meta.names, (char*) name);
 
203
        s = set_get(u->names, (char*) name);
201
204
        free(t);
202
205
 
203
206
        if (!s)
206
209
        if ((r = unit_name_to_instance(s, &i)) < 0)
207
210
                return r;
208
211
 
209
 
        u->meta.id = s;
 
212
        u->id = s;
210
213
 
211
 
        free(u->meta.instance);
212
 
        u->meta.instance = i;
 
214
        free(u->instance);
 
215
        u->instance = i;
213
216
 
214
217
        unit_add_to_dbus_queue(u);
215
218
 
224
227
        if (!(s = strdup(description)))
225
228
                return -ENOMEM;
226
229
 
227
 
        free(u->meta.description);
228
 
        u->meta.description = s;
 
230
        free(u->description);
 
231
        u->description = s;
229
232
 
230
233
        unit_add_to_dbus_queue(u);
231
234
        return 0;
234
237
bool unit_check_gc(Unit *u) {
235
238
        assert(u);
236
239
 
237
 
        if (u->meta.load_state == UNIT_STUB)
 
240
        if (u->load_state == UNIT_STUB)
238
241
                return true;
239
242
 
240
243
        if (UNIT_VTABLE(u)->no_gc)
241
244
                return true;
242
245
 
243
 
        if (u->meta.no_gc)
 
246
        if (u->no_gc)
244
247
                return true;
245
248
 
246
 
        if (u->meta.job)
 
249
        if (u->job)
247
250
                return true;
248
251
 
249
252
        if (unit_active_state(u) != UNIT_INACTIVE)
258
261
 
259
262
void unit_add_to_load_queue(Unit *u) {
260
263
        assert(u);
261
 
        assert(u->meta.type != _UNIT_TYPE_INVALID);
 
264
        assert(u->type != _UNIT_TYPE_INVALID);
262
265
 
263
 
        if (u->meta.load_state != UNIT_STUB || u->meta.in_load_queue)
 
266
        if (u->load_state != UNIT_STUB || u->in_load_queue)
264
267
                return;
265
268
 
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;
268
271
}
269
272
 
270
273
void unit_add_to_cleanup_queue(Unit *u) {
271
274
        assert(u);
272
275
 
273
 
        if (u->meta.in_cleanup_queue)
 
276
        if (u->in_cleanup_queue)
274
277
                return;
275
278
 
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;
278
281
}
279
282
 
280
283
void unit_add_to_gc_queue(Unit *u) {
281
284
        assert(u);
282
285
 
283
 
        if (u->meta.in_gc_queue || u->meta.in_cleanup_queue)
 
286
        if (u->in_gc_queue || u->in_cleanup_queue)
284
287
                return;
285
288
 
286
289
        if (unit_check_gc(u))
287
290
                return;
288
291
 
289
 
        LIST_PREPEND(Meta, gc_queue, u->meta.manager->gc_queue, &u->meta);
290
 
        u->meta.in_gc_queue = true;
291
 
 
292
 
        u->meta.manager->n_in_gc_queue ++;
293
 
 
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;
 
294
 
 
295
        u->manager->n_in_gc_queue ++;
 
296
 
 
297
        if (u->manager->gc_queue_timestamp <= 0)
 
298
                u->manager->gc_queue_timestamp = now(CLOCK_MONOTONIC);
296
299
}
297
300
 
298
301
void unit_add_to_dbus_queue(Unit *u) {
299
302
        assert(u);
300
 
        assert(u->meta.type != _UNIT_TYPE_INVALID);
 
303
        assert(u->type != _UNIT_TYPE_INVALID);
301
304
 
302
 
        if (u->meta.load_state == UNIT_STUB || u->meta.in_dbus_queue)
 
305
        if (u->load_state == UNIT_STUB || u->in_dbus_queue)
303
306
                return;
304
307
 
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;
308
311
                return;
309
312
        }
310
313
 
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;
313
316
}
314
317
 
315
318
static void bidi_set_free(Unit *u, Set *s) {
325
328
                UnitDependency d;
326
329
 
327
330
                for (d = 0; d < _UNIT_DEPENDENCY_MAX; d++)
328
 
                        set_remove(other->meta.dependencies[d], u);
 
331
                        set_remove(other->dependencies[d], u);
329
332
 
330
333
                unit_add_to_gc_queue(other);
331
334
        }
342
345
 
343
346
        bus_unit_send_removed_signal(u);
344
347
 
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);
348
351
 
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);
351
354
 
352
 
        if (u->meta.job)
353
 
                job_free(u->meta.job);
 
355
        if (u->job)
 
356
                job_free(u->job);
354
357
 
355
358
        for (d = 0; d < _UNIT_DEPENDENCY_MAX; d++)
356
 
                bidi_set_free(u, u->meta.dependencies[d]);
357
 
 
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);
360
 
 
361
 
        if (u->meta.in_load_queue)
362
 
                LIST_REMOVE(Meta, load_queue, u->meta.manager->load_queue, &u->meta);
363
 
 
364
 
        if (u->meta.in_dbus_queue)
365
 
                LIST_REMOVE(Meta, dbus_queue, u->meta.manager->dbus_unit_queue, &u->meta);
366
 
 
367
 
        if (u->meta.in_cleanup_queue)
368
 
                LIST_REMOVE(Meta, cleanup_queue, u->meta.manager->cleanup_queue, &u->meta);
369
 
 
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]);
 
360
 
 
361
        if (u->type != _UNIT_TYPE_INVALID)
 
362
                LIST_REMOVE(Unit, units_by_type, u->manager->units_by_type[u->type], u);
 
363
 
 
364
        if (u->in_load_queue)
 
365
                LIST_REMOVE(Unit, load_queue, u->manager->load_queue, u);
 
366
 
 
367
        if (u->in_dbus_queue)
 
368
                LIST_REMOVE(Unit, dbus_queue, u->manager->dbus_unit_queue, u);
 
369
 
 
370
        if (u->in_cleanup_queue)
 
371
                LIST_REMOVE(Unit, cleanup_queue, u->manager->cleanup_queue, u);
 
372
 
 
373
        if (u->in_gc_queue) {
 
374
                LIST_REMOVE(Unit, gc_queue, u->manager->gc_queue, u);
 
375
                u->manager->n_in_gc_queue--;
373
376
        }
374
377
 
375
 
        cgroup_bonding_free_list(u->meta.cgroup_bondings, u->meta.manager->n_reloading <= 0);
376
 
        cgroup_attribute_free_list(u->meta.cgroup_attributes);
377
 
 
378
 
        free(u->meta.description);
379
 
        free(u->meta.fragment_path);
380
 
 
381
 
        set_free_free(u->meta.names);
382
 
 
383
 
        condition_free_list(u->meta.conditions);
384
 
 
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);
 
380
 
 
381
        free(u->description);
 
382
        free(u->fragment_path);
 
383
        free(u->instance);
 
384
 
 
385
        set_free_free(u->names);
 
386
 
 
387
        condition_free_list(u->conditions);
 
388
 
 
389
        while (u->refs)
 
390
                unit_ref_unset(u->refs);
 
391
 
386
392
        free(u);
387
393
}
388
394
 
389
395
UnitActiveState unit_active_state(Unit *u) {
390
396
        assert(u);
391
397
 
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));
394
400
 
395
401
        /* After a reload it might happen that a unit is not correctly
427
433
        assert(u);
428
434
        assert(other);
429
435
 
430
 
        complete_move(&u->meta.names, &other->meta.names);
431
 
 
432
 
        set_free_free(other->meta.names);
433
 
        other->meta.names = NULL;
434
 
        other->meta.id = NULL;
435
 
 
436
 
        SET_FOREACH(t, u->meta.names, i)
437
 
                assert_se(hashmap_replace(u->meta.manager->units, t, u) == 0);
 
436
        complete_move(&u->names, &other->names);
 
437
 
 
438
        set_free_free(other->names);
 
439
        other->names = NULL;
 
440
        other->id = NULL;
 
441
 
 
442
        SET_FOREACH(t, u->names, i)
 
443
                assert_se(hashmap_replace(u->manager->units, t, u) == 0);
438
444
}
439
445
 
440
446
static void merge_dependencies(Unit *u, Unit *other, UnitDependency d) {
447
453
        assert(d < _UNIT_DEPENDENCY_MAX);
448
454
 
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;
452
458
 
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) {
455
461
 
456
462
                                if (r == -EEXIST)
457
 
                                        set_remove(back->meta.dependencies[k], other);
 
463
                                        set_remove(back->dependencies[k], other);
458
464
                                else
459
465
                                        assert(r == -ENOENT);
460
466
                        }
461
467
        }
462
468
 
463
 
        complete_move(&u->meta.dependencies[d], &other->meta.dependencies[d]);
 
469
        complete_move(&u->dependencies[d], &other->dependencies[d]);
464
470
 
465
 
        set_free(other->meta.dependencies[d]);
466
 
        other->meta.dependencies[d] = NULL;
 
471
        set_free(other->dependencies[d]);
 
472
        other->dependencies[d] = NULL;
467
473
}
468
474
 
469
475
int unit_merge(Unit *u, Unit *other) {
471
477
 
472
478
        assert(u);
473
479
        assert(other);
474
 
        assert(u->meta.manager == other->meta.manager);
475
 
        assert(u->meta.type != _UNIT_TYPE_INVALID);
 
480
        assert(u->manager == other->manager);
 
481
        assert(u->type != _UNIT_TYPE_INVALID);
476
482
 
477
483
        other = unit_follow_merge(other);
478
484
 
479
485
        if (other == u)
480
486
                return 0;
481
487
 
482
 
        if (u->meta.type != other->meta.type)
483
 
                return -EINVAL;
484
 
 
485
 
        if (!u->meta.instance != !other->meta.instance)
486
 
                return -EINVAL;
487
 
 
488
 
        if (other->meta.load_state != UNIT_STUB &&
489
 
            other->meta.load_state != UNIT_ERROR)
 
488
        if (u->type != other->type)
 
489
                return -EINVAL;
 
490
 
 
491
        if (!u->instance != !other->instance)
 
492
                return -EINVAL;
 
493
 
 
494
        if (other->load_state != UNIT_STUB &&
 
495
            other->load_state != UNIT_ERROR)
490
496
                return -EEXIST;
491
497
 
492
 
        if (other->meta.job)
 
498
        if (other->job)
493
499
                return -EEXIST;
494
500
 
495
501
        if (!UNIT_IS_INACTIVE_OR_FAILED(unit_active_state(other)))
498
504
        /* Merge names */
499
505
        merge_names(u, other);
500
506
 
 
507
        /* Redirect all references */
 
508
        while (other->refs)
 
509
                unit_ref_set(other->refs, u);
 
510
 
501
511
        /* Merge dependencies */
502
512
        for (d = 0; d < _UNIT_DEPENDENCY_MAX; d++)
503
513
                merge_dependencies(u, other, d);
504
514
 
505
 
        other->meta.load_state = UNIT_MERGED;
506
 
        other->meta.merged_into = u;
 
515
        other->load_state = UNIT_MERGED;
 
516
        other->merged_into = u;
507
517
 
508
518
        /* If there is still some data attached to the other node, we
509
519
         * don't need it anymore, and can free it. */
510
 
        if (other->meta.load_state != UNIT_STUB)
 
520
        if (other->load_state != UNIT_STUB)
511
521
                if (UNIT_VTABLE(other)->done)
512
522
                        UNIT_VTABLE(other)->done(other);
513
523
 
526
536
        assert(name);
527
537
 
528
538
        if (unit_name_is_template(name)) {
529
 
                if (!u->meta.instance)
 
539
                if (!u->instance)
530
540
                        return -EINVAL;
531
541
 
532
 
                if (!(s = unit_name_replace_instance(name, u->meta.instance)))
 
542
                if (!(s = unit_name_replace_instance(name, u->instance)))
533
543
                        return -ENOMEM;
534
544
 
535
545
                name = s;
536
546
        }
537
547
 
538
 
        if (!(other = manager_get_unit(u->meta.manager, name)))
 
548
        if (!(other = manager_get_unit(u->manager, name)))
539
549
                r = unit_add_name(u, name);
540
550
        else
541
551
                r = unit_merge(u, other);
547
557
Unit* unit_follow_merge(Unit *u) {
548
558
        assert(u);
549
559
 
550
 
        while (u->meta.load_state == UNIT_MERGED)
551
 
                assert_se(u = u->meta.merged_into);
 
560
        while (u->load_state == UNIT_MERGED)
 
561
                assert_se(u = u->merged_into);
552
562
 
553
563
        return u;
554
564
}
561
571
 
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)
570
584
                return 0;
571
585
 
572
586
        /* If syslog or kernel logging is requested, make sure our own
573
587
         * logging daemon is run first. */
574
588
 
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)
577
591
                        return r;
578
592
 
579
593
        return 0;
582
596
const char *unit_description(Unit *u) {
583
597
        assert(u);
584
598
 
585
 
        if (u->meta.description)
586
 
                return u->meta.description;
 
599
        if (u->description)
 
600
                return u->description;
587
601
 
588
 
        return strna(u->meta.id);
 
602
        return strna(u->id);
589
603
}
590
604
 
591
605
void unit_dump(Unit *u, FILE *f, const char *prefix) {
603
617
        Unit *following;
604
618
 
605
619
        assert(u);
606
 
        assert(u->meta.type >= 0);
 
620
        assert(u->type >= 0);
607
621
 
608
622
        if (!prefix)
609
623
                prefix = "";
622
636
                "%s\tInactive Enter Timestamp: %s\n"
623
637
                "%s\tGC Check Good: %s\n"
624
638
                "%s\tNeed Daemon Reload: %s\n",
625
 
                prefix, u->meta.id,
 
639
                prefix, u->id,
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)));
636
650
 
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);
639
653
 
640
654
        if ((following = unit_following(u)))
641
 
                fprintf(f, "%s\tFollowing: %s\n", prefix, following->meta.id);
642
 
 
643
 
        if (u->meta.fragment_path)
644
 
                fprintf(f, "%s\tFragment Path: %s\n", prefix, u->meta.fragment_path);
645
 
 
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));
648
 
 
649
 
        condition_dump_list(u->meta.conditions, f, prefix);
650
 
 
651
 
        if (dual_timestamp_is_set(&u->meta.condition_timestamp))
 
655
                fprintf(f, "%s\tFollowing: %s\n", prefix, following->id);
 
656
 
 
657
        if (u->fragment_path)
 
658
                fprintf(f, "%s\tFragment Path: %s\n", prefix, u->fragment_path);
 
659
 
 
660
        if (u->job_timeout > 0)
 
661
                fprintf(f, "%s\tJob Timeout: %s\n", prefix, format_timespan(timespan, sizeof(timespan), u->job_timeout));
 
662
 
 
663
        condition_dump_list(u->conditions, f, prefix);
 
664
 
 
665
        if (dual_timestamp_is_set(&u->condition_timestamp))
652
666
                fprintf(f,
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));
657
671
 
658
672
        for (d = 0; d < _UNIT_DEPENDENCY_MAX; d++) {
659
673
                Unit *other;
660
674
 
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);
663
677
        }
664
678
 
665
 
        if (u->meta.load_state == UNIT_LOADED) {
 
679
        if (u->load_state == UNIT_LOADED) {
666
680
                CGroupBonding *b;
667
681
                CGroupAttribute *a;
668
682
 
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));
684
698
 
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);
688
702
 
689
 
                LIST_FOREACH(by_unit, a, u->meta.cgroup_attributes) {
 
703
                LIST_FOREACH(by_unit, a, u->cgroup_attributes) {
690
704
                        char *v = NULL;
691
705
 
692
706
                        if (a->map_callback)
701
715
                if (UNIT_VTABLE(u)->dump)
702
716
                        UNIT_VTABLE(u)->dump(u, f, prefix2);
703
717
 
704
 
        } else if (u->meta.load_state == UNIT_MERGED)
 
718
        } else if (u->load_state == UNIT_MERGED)
705
719
                fprintf(f,
706
720
                        "%s\tMerged into: %s\n",
707
 
                        prefix, u->meta.merged_into->meta.id);
708
 
        else if (u->meta.load_state == UNIT_ERROR)
709
 
                fprintf(f, "%s\tLoad Error Code: %s\n", prefix, strerror(-u->meta.load_error));
710
 
 
711
 
 
712
 
        if (u->meta.job)
713
 
                job_dump(u->meta.job, f, prefix2);
 
721
                        prefix, u->merged_into->id);
 
722
        else if (u->load_state == UNIT_ERROR)
 
723
                fprintf(f, "%s\tLoad Error Code: %s\n", prefix, strerror(-u->load_error));
 
724
 
 
725
 
 
726
        if (u->job)
 
727
                job_dump(u->job, f, prefix2);
714
728
 
715
729
        free(p2);
716
730
}
725
739
        if ((r = unit_load_fragment(u)) < 0)
726
740
                return r;
727
741
 
728
 
        if (u->meta.load_state == UNIT_STUB)
 
742
        if (u->load_state == UNIT_STUB)
729
743
                return -ENOENT;
730
744
 
731
745
        /* Load drop-in directory data */
748
762
        if ((r = unit_load_fragment(u)) < 0)
749
763
                return r;
750
764
 
751
 
        if (u->meta.load_state == UNIT_STUB)
752
 
                u->meta.load_state = UNIT_LOADED;
 
765
        if (u->load_state == UNIT_STUB)
 
766
                u->load_state = UNIT_LOADED;
753
767
 
754
768
        /* Load drop-in directory data */
755
769
        if ((r = unit_load_dropin(unit_follow_merge(u))) < 0)
762
776
        assert(u);
763
777
        assert(target);
764
778
 
765
 
        if (target->meta.type != UNIT_TARGET)
 
779
        if (target->type != UNIT_TARGET)
766
780
                return 0;
767
781
 
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)
772
786
                return 0;
773
787
 
774
788
        /* If either side wants no automatic dependencies, then let's
775
789
         * skip this */
776
 
        if (!u->meta.default_dependencies ||
777
 
            !target->meta.default_dependencies)
 
790
        if (!u->default_dependencies ||
 
791
            !target->default_dependencies)
778
792
                return 0;
779
793
 
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))
782
796
                return 0;
783
797
 
784
798
        return unit_add_dependency(target, UNIT_AFTER, u, true);
800
814
        assert(u);
801
815
 
802
816
        for (k = 0; k < ELEMENTSOF(deps); k++)
803
 
                SET_FOREACH(target, u->meta.dependencies[deps[k]], i)
 
817
                SET_FOREACH(target, u->dependencies[deps[k]], i)
804
818
                        if ((r = unit_add_default_target_dependency(u, target)) < 0)
805
819
                                return r;
806
820
 
812
826
 
813
827
        assert(u);
814
828
 
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;
818
832
        }
819
833
 
820
 
        if (u->meta.type == _UNIT_TYPE_INVALID)
 
834
        if (u->type == _UNIT_TYPE_INVALID)
821
835
                return -EINVAL;
822
836
 
823
 
        if (u->meta.load_state != UNIT_STUB)
 
837
        if (u->load_state != UNIT_STUB)
824
838
                return 0;
825
839
 
826
840
        if (UNIT_VTABLE(u)->load)
827
841
                if ((r = UNIT_VTABLE(u)->load(u)) < 0)
828
842
                        goto fail;
829
843
 
830
 
        if (u->meta.load_state == UNIT_STUB) {
 
844
        if (u->load_state == UNIT_STUB) {
831
845
                r = -ENOENT;
832
846
                goto fail;
833
847
        }
834
848
 
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)
838
852
                        goto fail;
839
853
 
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) {
842
856
 
843
857
                log_error("More than one OnFailure= dependencies specified for %s but OnFailureIsolate= enabled. Refusing.",
844
 
                          u->meta.id);
 
858
                          u->id);
845
859
 
846
860
                r = -EINVAL;
847
861
                goto fail;
848
862
        }
849
863
 
850
 
        assert((u->meta.load_state != UNIT_MERGED) == !u->meta.merged_into);
 
864
        assert((u->load_state != UNIT_MERGED) == !u->merged_into);
851
865
 
852
866
        unit_add_to_dbus_queue(unit_follow_merge(u));
853
867
        unit_add_to_gc_queue(u);
855
869
        return 0;
856
870
 
857
871
fail:
858
 
        u->meta.load_state = UNIT_ERROR;
859
 
        u->meta.load_error = r;
 
872
        u->load_state = UNIT_ERROR;
 
873
        u->load_error = r;
860
874
        unit_add_to_dbus_queue(u);
 
875
        unit_add_to_gc_queue(u);
861
876
 
862
 
        log_debug("Failed to load configuration for %s: %s", u->meta.id, strerror(-r));
 
877
        log_debug("Failed to load configuration for %s: %s", u->id, strerror(-r));
863
878
 
864
879
        return r;
865
880
}
867
882
bool unit_condition_test(Unit *u) {
868
883
        assert(u);
869
884
 
870
 
        dual_timestamp_get(&u->meta.condition_timestamp);
871
 
        u->meta.condition_result = condition_test_list(u->meta.conditions);
 
885
        dual_timestamp_get(&u->condition_timestamp);
 
886
        u->condition_result = condition_test_list(u->conditions);
872
887
 
873
 
        return u->meta.condition_result;
 
888
        return u->condition_result;
874
889
}
875
890
 
876
891
/* Errors:
885
900
 
886
901
        assert(u);
887
902
 
888
 
        if (u->meta.load_state != UNIT_LOADED)
 
903
        if (u->load_state != UNIT_LOADED)
889
904
                return -EINVAL;
890
905
 
891
906
        /* If this is already started, then this will succeed. Note
902
917
         * but we don't want to recheck the condition in that case. */
903
918
        if (state != UNIT_ACTIVATING &&
904
919
            !unit_condition_test(u)) {
905
 
                log_debug("Starting of %s requested but condition failed. Ignoring.", u->meta.id);
 
920
                log_debug("Starting of %s requested but condition failed. Ignoring.", u->id);
906
921
                return -EALREADY;
907
922
        }
908
923
 
909
924
        /* Forward to the main object, if we aren't it. */
910
925
        if ((following = unit_following(u))) {
911
 
                log_debug("Redirecting start request from %s to %s.", u->meta.id, following->meta.id);
 
926
                log_debug("Redirecting start request from %s to %s.", u->id, following->id);
912
927
                return unit_start(following);
913
928
        }
914
929
 
924
939
 
925
940
        unit_add_to_dbus_queue(u);
926
941
 
927
 
        unit_status_printf(u, "Starting %s...\n", unit_description(u));
 
942
        unit_status_printf(u, NULL, "Starting %s...", unit_description(u));
928
943
        return UNIT_VTABLE(u)->start(u);
929
944
}
930
945
 
938
953
        assert(u);
939
954
 
940
955
        return unit_can_start(u) &&
941
 
                u->meta.allow_isolate;
 
956
                u->allow_isolate;
942
957
}
943
958
 
944
959
/* Errors:
957
972
                return -EALREADY;
958
973
 
959
974
        if ((following = unit_following(u))) {
960
 
                log_debug("Redirecting stop request from %s to %s.", u->meta.id, following->meta.id);
 
975
                log_debug("Redirecting stop request from %s to %s.", u->id, following->id);
961
976
                return unit_stop(following);
962
977
        }
963
978
 
966
981
 
967
982
        unit_add_to_dbus_queue(u);
968
983
 
969
 
        unit_status_printf(u, "Stopping %s...\n", unit_description(u));
 
984
        unit_status_printf(u, NULL, "Stopping %s...", unit_description(u));
970
985
        return UNIT_VTABLE(u)->stop(u);
971
986
}
972
987
 
981
996
 
982
997
        assert(u);
983
998
 
984
 
        if (u->meta.load_state != UNIT_LOADED)
 
999
        if (u->load_state != UNIT_LOADED)
985
1000
                return -EINVAL;
986
1001
 
987
1002
        if (!unit_can_reload(u))
995
1010
                return -ENOEXEC;
996
1011
 
997
1012
        if ((following = unit_following(u))) {
998
 
                log_debug("Redirecting reload request from %s to %s.", u->meta.id, following->meta.id);
 
1013
                log_debug("Redirecting reload request from %s to %s.", u->id, following->id);
999
1014
                return unit_reload(following);
1000
1015
        }
1001
1016
 
1024
1039
        /* If this service shall be shut down when unneeded then do
1025
1040
         * so. */
1026
1041
 
1027
 
        if (!u->meta.stop_when_unneeded)
 
1042
        if (!u->stop_when_unneeded)
1028
1043
                return;
1029
1044
 
1030
1045
        if (!UNIT_IS_ACTIVE_OR_ACTIVATING(unit_active_state(u)))
1031
1046
                return;
1032
1047
 
1033
 
        SET_FOREACH(other, u->meta.dependencies[UNIT_REQUIRED_BY], i)
1034
 
                if (!UNIT_IS_INACTIVE_OR_DEACTIVATING(unit_active_state(other)))
1035
 
                        return;
1036
 
 
1037
 
        SET_FOREACH(other, u->meta.dependencies[UNIT_REQUIRED_BY_OVERRIDABLE], i)
1038
 
                if (!UNIT_IS_INACTIVE_OR_DEACTIVATING(unit_active_state(other)))
1039
 
                        return;
1040
 
 
1041
 
        SET_FOREACH(other, u->meta.dependencies[UNIT_WANTED_BY], i)
1042
 
                if (!UNIT_IS_INACTIVE_OR_DEACTIVATING(unit_active_state(other)))
1043
 
                        return;
1044
 
 
1045
 
        SET_FOREACH(other, u->meta.dependencies[UNIT_BOUND_BY], i)
1046
 
                if (!UNIT_IS_INACTIVE_OR_DEACTIVATING(unit_active_state(other)))
1047
 
                        return;
1048
 
 
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))
 
1050
                        return;
 
1051
 
 
1052
        SET_FOREACH(other, u->dependencies[UNIT_REQUIRED_BY_OVERRIDABLE], i)
 
1053
                if (unit_pending_active(other))
 
1054
                        return;
 
1055
 
 
1056
        SET_FOREACH(other, u->dependencies[UNIT_WANTED_BY], i)
 
1057
                if (unit_pending_active(other))
 
1058
                        return;
 
1059
 
 
1060
        SET_FOREACH(other, u->dependencies[UNIT_BOUND_BY], i)
 
1061
                if (unit_pending_active(other))
 
1062
                        return;
 
1063
 
 
1064
        log_info("Service %s is not needed anymore. Stopping.", u->id);
1050
1065
 
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);
1053
1068
}
1054
1069
 
1055
1070
static void retroactively_start_dependencies(Unit *u) {
1059
1074
        assert(u);
1060
1075
        assert(UNIT_IS_ACTIVE_OR_ACTIVATING(unit_active_state(u)));
1061
1076
 
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);
1066
 
 
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);
1071
 
 
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);
1076
 
 
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);
1081
 
 
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);
1086
 
 
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);
1090
 
 
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);
 
1081
 
 
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);
 
1086
 
 
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);
 
1091
 
 
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);
 
1096
 
 
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);
 
1101
 
 
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);
 
1105
 
 
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);
1094
1109
}
1095
1110
 
1096
1111
static void retroactively_stop_dependencies(Unit *u) {
1101
1116
        assert(UNIT_IS_INACTIVE_OR_DEACTIVATING(unit_active_state(u)));
1102
1117
 
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);
 
1122
}
 
1123
 
 
1124
static void check_unneeded_dependencies(Unit *u) {
 
1125
        Iterator i;
 
1126
        Unit *other;
 
1127
 
 
1128
        assert(u);
 
1129
        assert(UNIT_IS_INACTIVE_OR_DEACTIVATING(unit_active_state(u)));
1107
1130
 
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);
1127
1150
}
1132
1155
 
1133
1156
        assert(u);
1134
1157
 
1135
 
        if (set_size(u->meta.dependencies[UNIT_ON_FAILURE]) <= 0)
 
1158
        if (set_size(u->dependencies[UNIT_ON_FAILURE]) <= 0)
1136
1159
                return;
1137
1160
 
1138
 
        log_info("Triggering OnFailure= dependencies of %s.", u->meta.id);
 
1161
        log_info("Triggering OnFailure= dependencies of %s.", u->id);
1139
1162
 
1140
 
        SET_FOREACH(other, u->meta.dependencies[UNIT_ON_FAILURE], i) {
 
1163
        SET_FOREACH(other, u->dependencies[UNIT_ON_FAILURE], i) {
1141
1164
                int r;
1142
1165
 
1143
 
                if ((r = manager_add_job(u->meta.manager, JOB_START, other, u->meta.on_failure_isolate ? JOB_ISOLATE : JOB_REPLACE, true, NULL, NULL)) < 0)
 
1166
                if ((r = manager_add_job(u->manager, JOB_START, other, u->on_failure_isolate ? JOB_ISOLATE : JOB_REPLACE, true, NULL, NULL)) < 0)
1144
1167
                        log_error("Failed to enqueue OnFailure= job: %s", strerror(-r));
1145
1168
        }
1146
1169
}
1158
1181
         * behaviour here. For example: if a mount point is remounted
1159
1182
         * this function will be called too! */
1160
1183
 
1161
 
        if (u->meta.manager->n_reloading <= 0) {
 
1184
        if (u->manager->n_reloading <= 0) {
1162
1185
                dual_timestamp ts;
1163
1186
 
1164
1187
                dual_timestamp_get(&ts);
1165
1188
 
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;
1170
1193
 
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;
1175
1198
 
1176
1199
                timer_unit_notify(u, ns);
1177
1200
                path_unit_notify(u, ns);
1178
1201
        }
1179
1202
 
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);
1182
1205
 
1183
 
        if (u->meta.job) {
 
1206
        if (u->job) {
1184
1207
                unexpected = false;
1185
1208
 
1186
 
                if (u->meta.job->state == JOB_WAITING)
 
1209
                if (u->job->state == JOB_WAITING)
1187
1210
 
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);
1192
1215
 
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. */
1196
1219
 
1197
 
                switch (u->meta.job->type) {
 
1220
                switch (u->job->type) {
1198
1221
 
1199
1222
                case JOB_START:
1200
1223
                case JOB_VERIFY_ACTIVE:
1201
1224
 
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;
1206
1229
 
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);
1209
1232
                        }
1210
1233
 
1211
1234
                        break;
1213
1236
                case JOB_RELOAD:
1214
1237
                case JOB_RELOAD_OR_START:
1215
1238
 
1216
 
                        if (u->meta.job->state == JOB_RUNNING) {
 
1239
                        if (u->job->state == JOB_RUNNING) {
1217
1240
                                if (ns == UNIT_ACTIVE)
1218
 
                                        job_finish_and_invalidate(u->meta.job, reload_success ? JOB_DONE : JOB_FAILED);
 
1241
                                        job_finish_and_invalidate(u->job, reload_success ? JOB_DONE : JOB_FAILED);
1219
1242
                                else if (ns != UNIT_ACTIVATING && ns != UNIT_RELOADING) {
1220
1243
                                        unexpected = true;
1221
1244
 
1222
1245
                                        if (UNIT_IS_INACTIVE_OR_FAILED(ns))
1223
 
                                                job_finish_and_invalidate(u->meta.job, ns == UNIT_FAILED ? JOB_FAILED : JOB_DONE);
 
1246
                                                job_finish_and_invalidate(u->job, ns == UNIT_FAILED ? JOB_FAILED : JOB_DONE);
1224
1247
                                }
1225
1248
                        }
1226
1249
 
1231
1254
                case JOB_TRY_RESTART:
1232
1255
 
1233
1256
                        if (UNIT_IS_INACTIVE_OR_FAILED(ns))
1234
 
                                job_finish_and_invalidate(u->meta.job, JOB_DONE);
1235
 
                        else if (u->meta.job->state == JOB_RUNNING && ns != UNIT_DEACTIVATING) {
 
1257
                                job_finish_and_invalidate(u->job, JOB_DONE);
 
1258
                        else if (u->job->state == JOB_RUNNING && ns != UNIT_DEACTIVATING) {
1236
1259
                                unexpected = true;
1237
 
                                job_finish_and_invalidate(u->meta.job, JOB_FAILED);
 
1260
                                job_finish_and_invalidate(u->job, JOB_FAILED);
1238
1261
                        }
1239
1262
 
1240
1263
                        break;
1246
1269
        } else
1247
1270
                unexpected = true;
1248
1271
 
1249
 
        if (u->meta.manager->n_reloading <= 0) {
 
1272
        if (u->manager->n_reloading <= 0) {
1250
1273
 
1251
1274
                /* If this state change happened without being
1252
1275
                 * requested by a job, then let's retroactively start
1262
1285
                                retroactively_stop_dependencies(u);
1263
1286
                }
1264
1287
 
 
1288
                /* stop unneeded units regardless if going down was expected or not */
 
1289
                if (UNIT_IS_ACTIVE_OR_ACTIVATING(os) && UNIT_IS_INACTIVE_OR_DEACTIVATING(ns))
 
1290
                        check_unneeded_dependencies(u);
 
1291
 
1265
1292
                if (ns != os && ns == UNIT_FAILED) {
1266
 
                        log_notice("Unit %s entered failed state.", u->meta.id);
 
1293
                        log_notice("Unit %s entered failed state.", u->id);
1267
1294
                        unit_trigger_on_failure(u);
1268
1295
                }
1269
1296
        }
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);
1279
1306
 
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);
 
1312
                        u->in_audit = true;
1286
1313
                }
1287
1314
 
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);
1290
1317
 
1291
1318
        } else {
1292
1319
 
1293
1320
                /* We don't care about D-Bus here, since we'll get an
1294
1321
                 * asynchronous notification for it anyway. */
1295
1322
 
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) {
1300
1327
 
1301
1328
                        /* Hmm, if there was no start record written
1302
1329
                         * write it now, so that we always have a nice
1303
1330
                         * pair */
1304
 
                        if (!u->meta.in_audit) {
1305
 
                                manager_send_unit_audit(u->meta.manager, u, AUDIT_SERVICE_START, ns == UNIT_INACTIVE);
 
1331
                        if (!u->in_audit) {
 
1332
                                manager_send_unit_audit(u->manager, u, AUDIT_SERVICE_START, ns == UNIT_INACTIVE);
1306
1333
 
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);
1309
1336
                        } else
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);
1312
1339
 
1313
 
                        u->meta.in_audit = false;
 
1340
                        u->in_audit = false;
1314
1341
                }
1315
1342
        }
1316
1343
 
1317
 
        manager_recheck_syslog(u->meta.manager);
 
1344
        manager_recheck_journal(u->manager);
1318
1345
 
1319
1346
        /* Maybe we finished startup and are now ready for being
1320
1347
         * stopped because unneeded? */
1336
1363
        ev.data.ptr = w;
1337
1364
        ev.events = events;
1338
1365
 
1339
 
        if (epoll_ctl(u->meta.manager->epoll_fd,
 
1366
        if (epoll_ctl(u->manager->epoll_fd,
1340
1367
                      w->type == WATCH_INVALID ? EPOLL_CTL_ADD : EPOLL_CTL_MOD,
1341
1368
                      fd,
1342
1369
                      &ev) < 0)
1358
1385
 
1359
1386
        assert(w->type == WATCH_FD);
1360
1387
        assert(w->data.unit == u);
1361
 
        assert_se(epoll_ctl(u->meta.manager->epoll_fd, EPOLL_CTL_DEL, w->fd, NULL) >= 0);
 
1388
        assert_se(epoll_ctl(u->manager->epoll_fd, EPOLL_CTL_DEL, w->fd, NULL) >= 0);
1362
1389
 
1363
1390
        w->fd = -1;
1364
1391
        w->type = WATCH_INVALID;
1372
1399
        /* Watch a specific PID. We only support one unit watching
1373
1400
         * each PID for now. */
1374
1401
 
1375
 
        return hashmap_put(u->meta.manager->watch_pids, LONG_TO_PTR(pid), u);
 
1402
        return hashmap_put(u->manager->watch_pids, LONG_TO_PTR(pid), u);
1376
1403
}
1377
1404
 
1378
1405
void unit_unwatch_pid(Unit *u, pid_t pid) {
1379
1406
        assert(u);
1380
1407
        assert(pid >= 1);
1381
1408
 
1382
 
        hashmap_remove_value(u->meta.manager->watch_pids, LONG_TO_PTR(pid), u);
 
1409
        hashmap_remove_value(u->manager->watch_pids, LONG_TO_PTR(pid), u);
1383
1410
}
1384
1411
 
1385
1412
int unit_watch_timer(Unit *u, usec_t delay, Watch *w) {
1432
1459
                ev.data.ptr = w;
1433
1460
                ev.events = EPOLLIN;
1434
1461
 
1435
 
                if (epoll_ctl(u->meta.manager->epoll_fd, EPOLL_CTL_ADD, fd, &ev) < 0)
 
1462
                if (epoll_ctl(u->manager->epoll_fd, EPOLL_CTL_ADD, fd, &ev) < 0)
1436
1463
                        goto fail;
1437
1464
        }
1438
1465
 
1460
1487
        assert(w->data.unit == u);
1461
1488
        assert(w->fd >= 0);
1462
1489
 
1463
 
        assert_se(epoll_ctl(u->meta.manager->epoll_fd, EPOLL_CTL_DEL, w->fd, NULL) >= 0);
 
1490
        assert_se(epoll_ctl(u->manager->epoll_fd, EPOLL_CTL_DEL, w->fd, NULL) >= 0);
1464
1491
        close_nointr_nofail(w->fd);
1465
1492
 
1466
1493
        w->fd = -1;
1513
1540
                [UNIT_AFTER] = UNIT_BEFORE,
1514
1541
                [UNIT_ON_FAILURE] = _UNIT_DEPENDENCY_INVALID,
1515
1542
                [UNIT_REFERENCES] = UNIT_REFERENCED_BY,
1516
 
                [UNIT_REFERENCED_BY] = UNIT_REFERENCES
 
1543
                [UNIT_REFERENCED_BY] = UNIT_REFERENCES,
 
1544
                [UNIT_TRIGGERS] = UNIT_TRIGGERED_BY,
 
1545
                [UNIT_TRIGGERED_BY] = UNIT_TRIGGERS,
 
1546
                [UNIT_PROPAGATE_RELOAD_TO] = UNIT_PROPAGATE_RELOAD_FROM,
 
1547
                [UNIT_PROPAGATE_RELOAD_FROM] = UNIT_PROPAGATE_RELOAD_TO
1517
1548
        };
1518
1549
        int r, q = 0, v = 0, w = 0;
1519
1550
 
1529
1560
        if (u == other)
1530
1561
                return 0;
1531
1562
 
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)
1533
1564
                return r;
1534
1565
 
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)
1537
1568
                        return r;
1538
1569
 
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)
1542
1573
                        return r;
1543
1574
 
1544
 
        if ((q = set_put(u->meta.dependencies[d], other)) < 0)
 
1575
        if ((q = set_put(u->dependencies[d], other)) < 0)
1545
1576
                return q;
1546
1577
 
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) {
1549
1580
                        r = v;
1550
1581
                        goto fail;
1551
1582
                }
1552
1583
 
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) {
1555
1586
                        r = w;
1556
1587
                        goto fail;
1557
1588
                }
1558
1589
 
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)
1560
1591
                        goto fail;
1561
1592
        }
1562
1593
 
1565
1596
 
1566
1597
fail:
1567
1598
        if (q > 0)
1568
 
                set_remove(u->meta.dependencies[d], other);
 
1599
                set_remove(u->dependencies[d], other);
1569
1600
 
1570
1601
        if (v > 0)
1571
 
                set_remove(other->meta.dependencies[inverse_table[d]], u);
 
1602
                set_remove(other->dependencies[inverse_table[d]], u);
1572
1603
 
1573
1604
        if (w > 0)
1574
 
                set_remove(u->meta.dependencies[UNIT_REFERENCES], other);
 
1605
                set_remove(u->dependencies[UNIT_REFERENCES], other);
1575
1606
 
1576
1607
        return r;
1577
1608
}
1604
1635
                return name;
1605
1636
        }
1606
1637
 
1607
 
        if (u->meta.instance)
1608
 
                s = unit_name_replace_instance(name, u->meta.instance);
 
1638
        if (u->instance)
 
1639
                s = unit_name_replace_instance(name, u->instance);
1609
1640
        else {
1610
1641
                char *i;
1611
1642
 
1612
 
                if (!(i = unit_name_to_prefix(u->meta.id)))
 
1643
                if (!(i = unit_name_to_prefix(u->id)))
1613
1644
                        return NULL;
1614
1645
 
1615
1646
                s = unit_name_replace_instance(name, i);
1634
1665
        if (!(name = resolve_template(u, name, path, &s)))
1635
1666
                return -ENOMEM;
1636
1667
 
1637
 
        if ((r = manager_load_unit(u->meta.manager, name, path, NULL, &other)) < 0)
 
1668
        if ((r = manager_load_unit(u->manager, name, path, NULL, &other)) < 0)
1638
1669
                goto finish;
1639
1670
 
1640
1671
        r = unit_add_dependency(u, d, other, add_reference);
1655
1686
        if (!(name = resolve_template(u, name, path, &s)))
1656
1687
                return -ENOMEM;
1657
1688
 
1658
 
        if ((r = manager_load_unit(u->meta.manager, name, path, NULL, &other)) < 0)
 
1689
        if ((r = manager_load_unit(u->manager, name, path, NULL, &other)) < 0)
1659
1690
                goto finish;
1660
1691
 
1661
1692
        r = unit_add_two_dependencies(u, d, e, other, add_reference);
1676
1707
        if (!(name = resolve_template(u, name, path, &s)))
1677
1708
                return -ENOMEM;
1678
1709
 
1679
 
        if ((r = manager_load_unit(u->meta.manager, name, path, NULL, &other)) < 0)
 
1710
        if ((r = manager_load_unit(u->manager, name, path, NULL, &other)) < 0)
1680
1711
                goto finish;
1681
1712
 
1682
1713
        r = unit_add_dependency(other, d, u, add_reference);
1697
1728
        if (!(name = resolve_template(u, name, path, &s)))
1698
1729
                return -ENOMEM;
1699
1730
 
1700
 
        if ((r = manager_load_unit(u->meta.manager, name, path, NULL, &other)) < 0)
 
1731
        if ((r = manager_load_unit(u->manager, name, path, NULL, &other)) < 0)
1701
1732
                goto finish;
1702
1733
 
1703
1734
        if ((r = unit_add_two_dependencies(other, d, e, u, add_reference)) < 0)
1742
1773
 
1743
1774
        assert(u);
1744
1775
 
1745
 
        if (!u->meta.id)
 
1776
        if (!u->id)
1746
1777
                return NULL;
1747
1778
 
1748
 
        if (!(e = bus_path_escape(u->meta.id)))
 
1779
        if (!(e = bus_path_escape(u->id)))
1749
1780
                return NULL;
1750
1781
 
1751
1782
        p = strappend("/org/freedesktop/systemd1/unit/", e);
1775
1806
        if (streq(b->controller, SYSTEMD_CGROUP_CONTROLLER)) {
1776
1807
                CGroupBonding *l;
1777
1808
 
1778
 
                l = hashmap_get(u->meta.manager->cgroup_bondings, b->path);
 
1809
                l = hashmap_get(u->manager->cgroup_bondings, b->path);
1779
1810
                LIST_PREPEND(CGroupBonding, by_path, l, b);
1780
1811
 
1781
 
                if ((r = hashmap_replace(u->meta.manager->cgroup_bondings, b->path, l)) < 0) {
 
1812
                if ((r = hashmap_replace(u->manager->cgroup_bondings, b->path, l)) < 0) {
1782
1813
                        LIST_REMOVE(CGroupBonding, by_path, l, b);
1783
1814
                        return r;
1784
1815
                }
1785
1816
        }
1786
1817
 
1787
 
        LIST_PREPEND(CGroupBonding, by_unit, u->meta.cgroup_bondings, b);
 
1818
        LIST_PREPEND(CGroupBonding, by_unit, u->cgroup_bondings, b);
1788
1819
        b->unit = u;
1789
1820
 
1790
1821
        return 0;
1795
1826
 
1796
1827
        assert(u);
1797
1828
 
1798
 
        if (u->meta.instance) {
 
1829
        if (u->instance) {
1799
1830
                char *t;
1800
1831
 
1801
 
                t = unit_name_template(u->meta.id);
 
1832
                t = unit_name_template(u->id);
1802
1833
                if (!t)
1803
1834
                        return NULL;
1804
1835
 
1805
 
                p = join(u->meta.manager->cgroup_hierarchy, "/", t, "/", u->meta.instance, NULL);
 
1836
                p = join(u->manager->cgroup_hierarchy, "/", t, "/", u->instance, NULL);
1806
1837
                free(t);
1807
1838
        } else
1808
 
                p = join(u->meta.manager->cgroup_hierarchy, "/", u->meta.id, NULL);
 
1839
                p = join(u->manager->cgroup_hierarchy, "/", u->id, NULL);
1809
1840
 
1810
1841
        return p;
1811
1842
}
1839
1870
                return -ENOMEM;
1840
1871
        }
1841
1872
 
1842
 
        if (cgroup_bonding_find_list(u->meta.cgroup_bondings, controller)) {
 
1873
        if (cgroup_bonding_find_list(u->cgroup_bondings, controller)) {
1843
1874
                r = -EEXIST;
1844
1875
                goto fail;
1845
1876
        }
1876
1907
        if (!controller)
1877
1908
                controller = SYSTEMD_CGROUP_CONTROLLER;
1878
1909
 
1879
 
        if (cgroup_bonding_find_list(u->meta.cgroup_bondings, controller))
 
1910
        if (cgroup_bonding_find_list(u->cgroup_bondings, controller))
1880
1911
                return 0;
1881
1912
 
1882
1913
        if (!(b = new0(CGroupBonding, 1)))
1914
1945
        /* Adds in the default cgroups, if they weren't specified
1915
1946
         * otherwise. */
1916
1947
 
1917
 
        if (!u->meta.manager->cgroup_hierarchy)
 
1948
        if (!u->manager->cgroup_hierarchy)
1918
1949
                return 0;
1919
1950
 
1920
1951
        if ((r = unit_add_one_default_cgroup(u, NULL)) < 0)
1921
1952
                return r;
1922
1953
 
1923
 
        STRV_FOREACH(c, u->meta.manager->default_controllers)
 
1954
        STRV_FOREACH(c, u->manager->default_controllers)
1924
1955
                unit_add_one_default_cgroup(u, *c);
1925
1956
 
1926
 
        LIST_FOREACH(by_unit, a, u->meta.cgroup_attributes)
 
1957
        LIST_FOREACH(by_unit, a, u->cgroup_attributes)
1927
1958
                unit_add_one_default_cgroup(u, a->controller);
1928
1959
 
1929
1960
        return 0;
1932
1963
CGroupBonding* unit_get_default_cgroup(Unit *u) {
1933
1964
        assert(u);
1934
1965
 
1935
 
        return cgroup_bonding_find_list(u->meta.cgroup_bondings, SYSTEMD_CGROUP_CONTROLLER);
 
1966
        return cgroup_bonding_find_list(u->cgroup_bondings, SYSTEMD_CGROUP_CONTROLLER);
1936
1967
}
1937
1968
 
1938
1969
int unit_add_cgroup_attribute(Unit *u, const char *controller, const char *name, const char *value, CGroupAttributeMapCallback map_callback) {
1989
2020
 
1990
2021
        a->map_callback = map_callback;
1991
2022
 
1992
 
        LIST_PREPEND(CGroupAttribute, by_unit, u->meta.cgroup_attributes, a);
 
2023
        LIST_PREPEND(CGroupAttribute, by_unit, u->cgroup_attributes, a);
1993
2024
 
1994
2025
        r = 0;
1995
2026
 
2006
2037
        assert(type);
2007
2038
        assert(_found);
2008
2039
 
2009
 
        if (!(t = unit_name_change_suffix(u->meta.id, type)))
 
2040
        if (!(t = unit_name_change_suffix(u->id, type)))
2010
2041
                return -ENOMEM;
2011
2042
 
2012
2043
        assert(!unit_has_name(u, t));
2013
2044
 
2014
 
        r = manager_load_unit(u->meta.manager, t, NULL, NULL, _found);
 
2045
        r = manager_load_unit(u->manager, t, NULL, NULL, _found);
2015
2046
        free(t);
2016
2047
 
2017
2048
        assert(r < 0 || *_found != u);
2027
2058
        assert(type);
2028
2059
        assert(_found);
2029
2060
 
2030
 
        if (!(t = unit_name_change_suffix(u->meta.id, type)))
 
2061
        if (!(t = unit_name_change_suffix(u->id, type)))
2031
2062
                return -ENOMEM;
2032
2063
 
2033
2064
        assert(!unit_has_name(u, t));
2034
2065
 
2035
 
        found = manager_get_unit(u->meta.manager, t);
 
2066
        found = manager_get_unit(u->manager, t);
2036
2067
        free(t);
2037
2068
 
2038
2069
        if (!found)
2046
2077
        Unit *u = userdata;
2047
2078
        assert(u);
2048
2079
 
2049
 
        return unit_name_to_prefix_and_instance(u->meta.id);
 
2080
        return unit_name_to_prefix_and_instance(u->id);
2050
2081
}
2051
2082
 
2052
2083
static char *specifier_prefix(char specifier, void *data, void *userdata) {
2053
2084
        Unit *u = userdata;
2054
2085
        assert(u);
2055
2086
 
2056
 
        return unit_name_to_prefix(u->meta.id);
 
2087
        return unit_name_to_prefix(u->id);
2057
2088
}
2058
2089
 
2059
2090
static char *specifier_prefix_unescaped(char specifier, void *data, void *userdata) {
2062
2093
 
2063
2094
        assert(u);
2064
2095
 
2065
 
        if (!(p = unit_name_to_prefix(u->meta.id)))
 
2096
        if (!(p = unit_name_to_prefix(u->id)))
2066
2097
                return NULL;
2067
2098
 
2068
2099
        r = unit_name_unescape(p);
2075
2106
        Unit *u = userdata;
2076
2107
        assert(u);
2077
2108
 
2078
 
        if (u->meta.instance)
2079
 
                return unit_name_unescape(u->meta.instance);
 
2109
        if (u->instance)
 
2110
                return unit_name_unescape(u->instance);
2080
2111
 
2081
2112
        return strdup("");
2082
2113
}
2085
2116
        Unit *u = userdata;
2086
2117
        assert(u);
2087
2118
 
2088
 
        if (u->meta.instance)
2089
 
                return unit_name_path_unescape(u->meta.instance);
 
2119
        if (u->instance)
 
2120
                return unit_name_path_unescape(u->instance);
2090
2121
 
2091
 
        return unit_name_to_path(u->meta.instance);
 
2122
        return unit_name_to_path(u->instance);
2092
2123
}
2093
2124
 
2094
2125
static char *specifier_cgroup(char specifier, void *data, void *userdata) {
2104
2135
        assert(u);
2105
2136
 
2106
2137
        if (specifier == 'r')
2107
 
                return strdup(u->meta.manager->cgroup_hierarchy);
 
2138
                return strdup(u->manager->cgroup_hierarchy);
2108
2139
 
2109
 
        if (parent_of_path(u->meta.manager->cgroup_hierarchy, &p) < 0)
 
2140
        if (parent_of_path(u->manager->cgroup_hierarchy, &p) < 0)
2110
2141
                return strdup("");
2111
2142
 
2112
2143
        if (streq(p, "/")) {
2121
2152
        Unit *u = userdata;
2122
2153
        assert(u);
2123
2154
 
2124
 
        if (u->meta.manager->running_as == MANAGER_USER) {
 
2155
        if (u->manager->running_as == MANAGER_USER) {
2125
2156
                const char *e;
2126
2157
 
2127
2158
                e = getenv("XDG_RUNTIME_DIR");
2145
2176
         */
2146
2177
 
2147
2178
        const Specifier table[] = {
2148
 
                { 'n', specifier_string,              u->meta.id },
 
2179
                { 'n', specifier_string,              u->id },
2149
2180
                { 'N', specifier_prefix_and_instance, NULL },
2150
2181
                { 'p', specifier_prefix,              NULL },
2151
 
                { 'i', specifier_string,              u->meta.instance },
 
2182
                { 'i', specifier_string,              u->instance },
2152
2183
                { 0, NULL, NULL }
2153
2184
        };
2154
2185
 
2170
2201
         */
2171
2202
 
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 },
2225
2256
        /* Watch a specific name on the bus. We only support one unit
2226
2257
         * watching each name for now. */
2227
2258
 
2228
 
        return hashmap_put(u->meta.manager->watch_bus, name, u);
 
2259
        return hashmap_put(u->manager->watch_bus, name, u);
2229
2260
}
2230
2261
 
2231
2262
void unit_unwatch_bus_name(Unit *u, const char *name) {
2232
2263
        assert(u);
2233
2264
        assert(name);
2234
2265
 
2235
 
        hashmap_remove_value(u->meta.manager->watch_bus, name, u);
 
2266
        hashmap_remove_value(u->manager->watch_bus, name, u);
2236
2267
}
2237
2268
 
2238
2269
bool unit_can_serialize(Unit *u) {
2254
2285
        if ((r = UNIT_VTABLE(u)->serialize(u, f, fds)) < 0)
2255
2286
                return r;
2256
2287
 
2257
 
        if (u->meta.job)
2258
 
                unit_serialize_item(u, f, "job", job_type_to_string(u->meta.job->type));
2259
 
 
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);
2265
 
 
2266
 
        if (dual_timestamp_is_set(&u->meta.condition_timestamp))
2267
 
                unit_serialize_item(u, f, "condition-result", yes_no(u->meta.condition_result));
 
2288
        if (u->job)
 
2289
                unit_serialize_item(u, f, "job", job_type_to_string(u->job->type));
 
2290
 
 
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);
 
2296
 
 
2297
        if (dual_timestamp_is_set(&u->condition_timestamp))
 
2298
                unit_serialize_item(u, f, "condition-result", yes_no(u->condition_result));
2268
2299
 
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);
2341
2372
                        else
2342
 
                                u->meta.deserialized_job = type;
 
2373
                                u->deserialized_job = type;
2343
2374
 
2344
2375
                        continue;
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);
2347
2378
                        continue;
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);
2350
2381
                        continue;
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);
2353
2384
                        continue;
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);
2356
2387
                        continue;
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);
2359
2390
                        continue;
2360
2391
                } else if (streq(l, "condition-result")) {
2361
2392
                        int b;
2363
2394
                        if ((b = parse_boolean(v)) < 0)
2364
2395
                                log_debug("Failed to parse condition result value %s", v);
2365
2396
                        else
2366
 
                                u->meta.condition_result = b;
 
2397
                                u->condition_result = b;
2367
2398
 
2368
2399
                        continue;
2369
2400
                }
2391
2422
        if (!(e = unit_name_build_escape(what+1, NULL, ".device")))
2392
2423
                return -ENOMEM;
2393
2424
 
2394
 
        r = manager_load_unit(u->meta.manager, e, NULL, NULL, &device);
 
2425
        r = manager_load_unit(u->manager, e, NULL, NULL, &device);
2395
2426
        free(e);
2396
2427
 
2397
2428
        if (r < 0)
2416
2447
                if ((r = UNIT_VTABLE(u)->coldplug(u)) < 0)
2417
2448
                        return r;
2418
2449
 
2419
 
        if (u->meta.deserialized_job >= 0) {
2420
 
                if ((r = manager_add_job(u->meta.manager, u->meta.deserialized_job, u, JOB_IGNORE_REQUIREMENTS, false, NULL, NULL)) < 0)
 
2450
        if (u->deserialized_job >= 0) {
 
2451
                if ((r = manager_add_job(u->manager, u->deserialized_job, u, JOB_IGNORE_REQUIREMENTS, false, NULL, NULL)) < 0)
2421
2452
                        return r;
2422
2453
 
2423
 
                u->meta.deserialized_job = _JOB_TYPE_INVALID;
 
2454
                u->deserialized_job = _JOB_TYPE_INVALID;
2424
2455
        }
2425
2456
 
2426
2457
        return 0;
2427
2458
}
2428
2459
 
2429
 
void unit_status_printf(Unit *u, const char *format, ...) {
 
2460
void unit_status_printf(Unit *u, const char *status, const char *format, ...) {
2430
2461
        va_list ap;
2431
2462
 
2432
2463
        assert(u);
2435
2466
        if (!UNIT_VTABLE(u)->show_status)
2436
2467
                return;
2437
2468
 
2438
 
        if (!manager_get_show_status(u->meta.manager))
 
2469
        if (!manager_get_show_status(u->manager))
2439
2470
                return;
2440
2471
 
2441
 
        if (!manager_is_booting_or_shutting_down(u->meta.manager))
 
2472
        if (!manager_is_booting_or_shutting_down(u->manager))
2442
2473
                return;
2443
2474
 
2444
2475
        va_start(ap, format);
2445
 
        status_vprintf(format, ap);
 
2476
        status_vprintf(status, true, format, ap);
2446
2477
        va_end(ap);
2447
2478
}
2448
2479
 
2449
2480
bool unit_need_daemon_reload(Unit *u) {
2450
2481
        assert(u);
2451
2482
 
2452
 
        if (u->meta.fragment_path) {
 
2483
        if (u->fragment_path) {
2453
2484
                struct stat st;
2454
2485
 
2455
2486
                zero(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? */
2458
2489
                        return true;
2459
2490
 
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)
2462
2493
                        return true;
2463
2494
        }
2464
2495
 
2492
2523
        if (UNIT_IS_INACTIVE_OR_DEACTIVATING(unit_active_state(u)))
2493
2524
                return true;
2494
2525
 
2495
 
        if (u->meta.job && u->meta.job->type == JOB_STOP)
 
2526
        if (u->job && u->job->type == JOB_STOP)
2496
2527
                return true;
2497
2528
 
2498
2529
        return false;
2501
2532
bool unit_pending_active(Unit *u) {
2502
2533
        assert(u);
2503
2534
 
2504
 
        /* Returns true if the unit is inactive or going down */
 
2535
        /* Returns true if the unit is active or going up */
2505
2536
 
2506
2537
        if (UNIT_IS_ACTIVE_OR_ACTIVATING(unit_active_state(u)))
2507
2538
                return true;
2508
2539
 
2509
 
        if (u->meta.job &&
2510
 
            (u->meta.job->type == JOB_START ||
2511
 
             u->meta.job->type == JOB_RELOAD_OR_START ||
2512
 
             u->meta.job->type == JOB_RESTART))
 
2540
        if (u->job &&
 
2541
            (u->job->type == JOB_START ||
 
2542
             u->job->type == JOB_RELOAD_OR_START ||
 
2543
             u->job->type == JOB_RESTART))
2513
2544
                return true;
2514
2545
 
2515
2546
        return false;
2567
2598
UnitFileState unit_get_unit_file_state(Unit *u) {
2568
2599
        assert(u);
2569
2600
 
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));
2574
 
 
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));
 
2605
 
 
2606
        return u->unit_file_state;
 
2607
}
 
2608
 
 
2609
Unit* unit_ref_set(UnitRef *ref, Unit *u) {
 
2610
        assert(ref);
 
2611
        assert(u);
 
2612
 
 
2613
        if (ref->unit)
 
2614
                unit_ref_unset(ref);
 
2615
 
 
2616
        ref->unit = u;
 
2617
        LIST_PREPEND(UnitRef, refs, u->refs, ref);
 
2618
        return u;
 
2619
}
 
2620
 
 
2621
void unit_ref_unset(UnitRef *ref) {
 
2622
        assert(ref);
 
2623
 
 
2624
        if (!ref->unit)
 
2625
                return;
 
2626
 
 
2627
        LIST_REMOVE(UnitRef, refs, ref->unit->refs, ref);
 
2628
        ref->unit = NULL;
2576
2629
}
2577
2630
 
2578
2631
static const char* const unit_load_state_table[_UNIT_LOAD_STATE_MAX] = {
2613
2666
        [UNIT_AFTER] = "After",
2614
2667
        [UNIT_REFERENCES] = "References",
2615
2668
        [UNIT_REFERENCED_BY] = "ReferencedBy",
2616
 
        [UNIT_ON_FAILURE] = "OnFailure"
 
2669
        [UNIT_ON_FAILURE] = "OnFailure",
 
2670
        [UNIT_TRIGGERS] = "Triggers",
 
2671
        [UNIT_TRIGGERED_BY] = "TriggeredBy",
 
2672
        [UNIT_PROPAGATE_RELOAD_TO] = "PropagateReloadTo",
 
2673
        [UNIT_PROPAGATE_RELOAD_FROM] = "PropagateReloadFrom"
2617
2674
};
2618
2675
 
2619
2676
DEFINE_STRING_TABLE_LOOKUP(unit_dependency, UnitDependency);