- /* Check if this attribute already exists. Note that we will
- * explicitly check for the value here too, as there are
- * attributes which accept multiple values. */
- a = cgroup_attribute_find_list(u->cgroup_attributes, controller, name);
- if (a) {
- if (streq(value, a->value)) {
- /* Exactly the same value is always OK, let's ignore this */
- if (ret)
- *ret = a;
-
- return 0;
- }
-
- if (semantics && !semantics->multiple) {
- char *v;
-
- /* If this is a single-item entry, we can
- * simply patch the existing attribute */
-
- v = strdup(value);
- if (!v)
- return -ENOMEM;
-
- free(a->value);
- a->value = v;
-
- if (ret)
- *ret = a;
- return 1;
- }
- }
-
- a = new0(CGroupAttribute, 1);
- if (!a)
- return -ENOMEM;
-
- if (c) {
- a->controller = c;
- c = NULL;
- } else
- a->controller = strdup(controller);
-
- a->name = strdup(name);
- a->value = strdup(value);
-
- if (!a->controller || !a->name || !a->value) {
- free(a->controller);
- free(a->name);
- free(a->value);
- free(a);
- return -ENOMEM;
- }
-
- a->semantics = semantics;
- a->unit = u;
-
- LIST_PREPEND(CGroupAttribute, by_unit, u->cgroup_attributes, a);
-
- if (ret)
- *ret = a;
-
- return 1;
-}
-
-int unit_load_related_unit(Unit *u, const char *type, Unit **_found) {
- char *t;
- int r;
-
- assert(u);
- assert(type);
- assert(_found);
-
- if (!(t = unit_name_change_suffix(u->id, type)))
- return -ENOMEM;
-
- assert(!unit_has_name(u, t));
-
- r = manager_load_unit(u->manager, t, NULL, NULL, _found);
- free(t);
-
- assert(r < 0 || *_found != u);
-
- return r;
-}
-
-int unit_get_related_unit(Unit *u, const char *type, Unit **_found) {
- Unit *found;
- char *t;
-
- assert(u);
- assert(type);
- assert(_found);
-
- if (!(t = unit_name_change_suffix(u->id, type)))
- return -ENOMEM;
-
- assert(!unit_has_name(u, t));
-
- found = manager_get_unit(u->manager, t);
- free(t);
-
- if (!found)
- return -ENOENT;
-
- *_found = found;
- return 0;
-}
-
-int unit_watch_bus_name(Unit *u, const char *name) {
- assert(u);
- assert(name);
-
- /* Watch a specific name on the bus. We only support one unit
- * watching each name for now. */
-
- return hashmap_put(u->manager->watch_bus, name, u);
-}
-
-void unit_unwatch_bus_name(Unit *u, const char *name) {
- assert(u);
- assert(name);
-
- hashmap_remove_value(u->manager->watch_bus, name, u);
-}
-
-bool unit_can_serialize(Unit *u) {
- assert(u);
-
- return UNIT_VTABLE(u)->serialize && UNIT_VTABLE(u)->deserialize_item;
-}
-
-int unit_serialize(Unit *u, FILE *f, FDSet *fds, bool serialize_jobs) {
- int r;
-
- assert(u);
- assert(f);
- assert(fds);
-
- if (!unit_can_serialize(u))
- return 0;
-
- if ((r = UNIT_VTABLE(u)->serialize(u, f, fds)) < 0)
- return r;
-
-
- if (serialize_jobs) {
- if (u->job) {
- fprintf(f, "job\n");
- job_serialize(u->job, f, fds);
- }
-
- if (u->nop_job) {
- fprintf(f, "job\n");
- job_serialize(u->nop_job, f, fds);
- }
- }
-
- dual_timestamp_serialize(f, "inactive-exit-timestamp", &u->inactive_exit_timestamp);
- dual_timestamp_serialize(f, "active-enter-timestamp", &u->active_enter_timestamp);
- dual_timestamp_serialize(f, "active-exit-timestamp", &u->active_exit_timestamp);
- dual_timestamp_serialize(f, "inactive-enter-timestamp", &u->inactive_enter_timestamp);
- dual_timestamp_serialize(f, "condition-timestamp", &u->condition_timestamp);
-
- if (dual_timestamp_is_set(&u->condition_timestamp))
- unit_serialize_item(u, f, "condition-result", yes_no(u->condition_result));