chiark / gitweb /
logger: fix return value
[elogind.git] / unit.c
diff --git a/unit.c b/unit.c
index 980c3711eb147d60075c416643d54e74bd57f69a..036c01648c6e017ee4d832e67d74a20e1c359fe9 100644 (file)
--- a/unit.c
+++ b/unit.c
@@ -260,6 +260,8 @@ void unit_free(Unit *u) {
 
         /* Detach from next 'bigger' objects */
 
+        cgroup_bonding_free_list(u->meta.cgroup_bondings);
+
         SET_FOREACH(t, u->meta.names, i)
                 hashmap_remove_value(u->meta.manager->units, t, u);
 
@@ -369,12 +371,12 @@ const char *unit_description(Unit *u) {
 }
 
 void unit_dump(Unit *u, FILE *f, const char *prefix) {
-
         char *t;
         UnitDependency d;
         Iterator i;
         char *p2;
         const char *prefix2;
+        CGroupBonding *b;
 
         assert(u);
 
@@ -413,6 +415,10 @@ void unit_dump(Unit *u, FILE *f, const char *prefix) {
                         fprintf(f, "%s\t%s: %s\n", prefix, unit_dependency_to_string(d), unit_id(other));
         }
 
+        LIST_FOREACH(by_unit, b, u->meta.cgroup_bondings)
+                fprintf(f, "%s\tControlGroup: %s:%s\n",
+                        prefix, b->controller, b->path);
+
         if (UNIT_VTABLE(u)->dump)
                 UNIT_VTABLE(u)->dump(u, f, prefix2);
 
@@ -972,6 +978,19 @@ int unit_add_dependency_by_name(Unit *u, UnitDependency d, const char *name) {
         return 0;
 }
 
+int unit_add_dependency_by_name_inverse(Unit *u, UnitDependency d, const char *name) {
+        Unit *other;
+        int r;
+
+        if ((r = manager_load_unit(u->meta.manager, name, &other)) < 0)
+                return r;
+
+        if ((r = unit_add_dependency(other, d, u)) < 0)
+                return r;
+
+        return 0;
+}
+
 int set_unit_path(const char *p) {
         char *cwd, *c;
         int r;
@@ -1001,10 +1020,10 @@ int set_unit_path(const char *p) {
         return 0;
 }
 
-char *unit_name_escape_path(const char *prefix, const char *path, const char *suffix) {
+char *unit_name_escape_path(const char *path, const char *suffix) {
         char *r, *t;
         const char *f;
-        size_t a, b, c;
+        size_t a, b;
 
         assert(path);
 
@@ -1017,22 +1036,16 @@ char *unit_name_escape_path(const char *prefix, const char *path, const char *su
          * escaping is hence reversible.
          */
 
-        if (!prefix)
-                prefix = "";
-
         if (!suffix)
                 suffix = "";
 
-        a = strlen(prefix);
-        b = strlen(path);
-        c = strlen(suffix);
+        a = strlen(path);
+        b = strlen(suffix);
 
-        if (!(r = new(char, a+b*4+c+1)))
+        if (!(r = new(char, a*4+b+1)))
                 return NULL;
 
-        memcpy(r, prefix, a);
-
-        for (f = path, t = r+a; *f; f++) {
+        for (f = path, t = r; *f; f++) {
                 if (*f == '/')
                         *(t++) = '.';
                 else if (*f == '.' || *f == '\\' || !strchr(VALID_CHARS, *f)) {
@@ -1044,7 +1057,7 @@ char *unit_name_escape_path(const char *prefix, const char *path, const char *su
                         *(t++) = *f;
         }
 
-        memcpy(t, suffix, c+1);
+        memcpy(t, suffix, b+1);
 
         return r;
 }
@@ -1066,6 +1079,138 @@ char *unit_dbus_path(Unit *u) {
         return p;
 }
 
+int unit_add_cgroup(Unit *u, CGroupBonding *b) {
+        CGroupBonding *l;
+        int r;
+
+        assert(u);
+        assert(b);
+        assert(b->path);
+
+        /* Ensure this hasn't been added yet */
+        assert(!b->unit);
+
+        l = hashmap_get(u->meta.manager->cgroup_bondings, b->path);
+        LIST_PREPEND(CGroupBonding, by_path, l, b);
+
+        if ((r = hashmap_replace(u->meta.manager->cgroup_bondings, b->path, l)) < 0) {
+                LIST_REMOVE(CGroupBonding, by_path, l, b);
+                return r;
+        }
+
+        LIST_PREPEND(CGroupBonding, by_unit, u->meta.cgroup_bondings, b);
+        b->unit = u;
+
+        return 0;
+}
+
+int unit_add_cgroup_from_text(Unit *u, const char *name) {
+        size_t n;
+        const char *p;
+        char *controller;
+        CGroupBonding *b;
+        int r;
+
+        assert(u);
+        assert(name);
+
+        /* Detect controller name */
+        n = strcspn(name, ":/");
+
+        /* Only controller name, no path? No path? */
+        if (name[n] == 0)
+                return -EINVAL;
+
+        if (n > 0) {
+                if (name[n] != ':')
+                        return -EINVAL;
+
+                p = name+n+1;
+        } else
+                p = name;
+
+        /* Insist in absolute paths */
+        if (p[0] != '/')
+                return -EINVAL;
+
+        if (!(controller = strndup(name, n)))
+                return -ENOMEM;
+
+        if (cgroup_bonding_find_list(u->meta.cgroup_bondings, controller)) {
+                free(controller);
+                return -EEXIST;
+        }
+
+        if (!(b = new0(CGroupBonding, 1))) {
+                free(controller);
+                return -ENOMEM;
+        }
+
+        b->controller = controller;
+
+        if (!(b->path = strdup(p))) {
+                r = -ENOMEM;
+                goto fail;
+        }
+
+        b->only_us = false;
+        b->clean_up = false;
+
+        if ((r = unit_add_cgroup(u, b)) < 0)
+                goto fail;
+
+        return 0;
+
+fail:
+        free(b->path);
+        free(b->controller);
+        free(b);
+
+        return r;
+}
+
+int unit_add_default_cgroup(Unit *u) {
+        CGroupBonding *b;
+        int r = -ENOMEM;
+
+        assert(u);
+
+        /* Adds in the default cgroup data, if it wasn't specified yet */
+
+        if (unit_get_default_cgroup(u))
+                return 0;
+
+        if (!(b = new0(CGroupBonding, 1)))
+                return -ENOMEM;
+
+        if (!(b->controller = strdup(u->meta.manager->cgroup_controller)))
+                goto fail;
+
+        if (asprintf(&b->path, "%s/%s", u->meta.manager->cgroup_hierarchy, unit_id(u)) < 0)
+                goto fail;
+
+        b->clean_up = true;
+        b->only_us = true;
+
+        if ((r = unit_add_cgroup(u, b)) < 0)
+                goto fail;
+
+        return 0;
+
+fail:
+        free(b->path);
+        free(b->controller);
+        free(b);
+
+        return r;
+}
+
+CGroupBonding* unit_get_default_cgroup(Unit *u) {
+        assert(u);
+
+        return cgroup_bonding_find_list(u->meta.cgroup_bondings, u->meta.manager->cgroup_controller);
+}
+
 static const char* const unit_type_table[_UNIT_TYPE_MAX] = {
         [UNIT_SERVICE] = "service",
         [UNIT_TIMER] = "timer",