chiark / gitweb /
core: expose consumed CPU time per unit
[elogind.git] / src / core / cgroup.c
index 97f656eb5d8f4deaa850f4cd21cd6675bde4ec1c..6b8abb4802ba76635b9ecaa0a17ff3ac796641af 100644 (file)
@@ -292,7 +292,7 @@ void cgroup_context_apply(CGroupContext *c, CGroupControllerMask mask, const cha
         if (mask == 0)
                 return;
 
-        /* Some cgroup attributes are not support on the root cgroup,
+        /* Some cgroup attributes are not supported on the root cgroup,
          * hence silently ignore */
         is_root = isempty(path) || path_equal(path, "/");
         if (is_root)
@@ -380,7 +380,7 @@ void cgroup_context_apply(CGroupContext *c, CGroupControllerMask mask, const cha
                 }
         }
 
-        if ((mask & CGROUP_MEMORY) & !is_root) {
+        if ((mask & CGROUP_MEMORY) && !is_root) {
                 if (c->memory_limit != (uint64_t) -1) {
                         char buf[DECIMAL_STR_MAX(uint64_t) + 1];
 
@@ -954,7 +954,7 @@ int manager_setup_cgroup(Manager *m) {
                 if (m->pin_cgroupfs_fd < 0)
                         return log_error_errno(errno, "Failed to open pin file: %m");
 
-                /* 6.  Always enable hierarchial support if it exists... */
+                /* 6.  Always enable hierarchical support if it exists... */
                 cg_set_attribute("memory", "/", "memory.use_hierarchy", "1");
         }
 
@@ -1029,16 +1029,100 @@ int manager_notify_cgroup_empty(Manager *m, const char *cgroup) {
         assert(cgroup);
 
         u = manager_get_unit_by_cgroup(m, cgroup);
-        if (u) {
-                r = cg_is_empty_recursive(SYSTEMD_CGROUP_CONTROLLER, u->cgroup_path, true);
-                if (r > 0) {
-                        if (UNIT_VTABLE(u)->notify_cgroup_empty)
-                                UNIT_VTABLE(u)->notify_cgroup_empty(u);
+        if (!u)
+                return 0;
 
-                        unit_add_to_gc_queue(u);
-                }
+        r = cg_is_empty_recursive(SYSTEMD_CGROUP_CONTROLLER, u->cgroup_path, true);
+        if (r <= 0)
+                return r;
+
+        if (UNIT_VTABLE(u)->notify_cgroup_empty)
+                UNIT_VTABLE(u)->notify_cgroup_empty(u);
+
+        unit_add_to_gc_queue(u);
+        return 0;
+}
+
+int unit_get_memory_current(Unit *u, uint64_t *ret) {
+        _cleanup_free_ char *v = NULL;
+        int r;
+
+        assert(u);
+        assert(ret);
+
+        if (!u->cgroup_path)
+                return -ENODATA;
+
+        if ((u->cgroup_realized_mask & CGROUP_MEMORY) == 0)
+                return -ENODATA;
+
+        r = cg_get_attribute("memory", u->cgroup_path, "memory.usage_in_bytes", &v);
+        if (r == -ENOENT)
+                return -ENODATA;
+        if (r < 0)
+                return r;
+
+        return safe_atou64(v, ret);
+}
+
+static int unit_get_cpu_usage_raw(Unit *u, nsec_t *ret) {
+        _cleanup_free_ char *v = NULL;
+        uint64_t ns;
+        int r;
+
+        assert(u);
+        assert(ret);
+
+        if (!u->cgroup_path)
+                return -ENODATA;
+
+        if ((u->cgroup_realized_mask & CGROUP_CPUACCT) == 0)
+                return -ENODATA;
+
+        r = cg_get_attribute("cpuacct", u->cgroup_path, "cpuacct.usage", &v);
+        if (r == -ENOENT)
+                return -ENODATA;
+        if (r < 0)
+                return r;
+
+        r = safe_atou64(v, &ns);
+        if (r < 0)
+                return r;
+
+        *ret = ns;
+        return 0;
+}
+
+int unit_get_cpu_usage(Unit *u, nsec_t *ret) {
+        nsec_t ns;
+        int r;
+
+        r = unit_get_cpu_usage_raw(u, &ns);
+        if (r < 0)
+                return r;
+
+        if (ns > u->cpuacct_usage_base)
+                ns -= u->cpuacct_usage_base;
+        else
+                ns = 0;
+
+        *ret = ns;
+        return 0;
+}
+
+int unit_reset_cpu_usage(Unit *u) {
+        nsec_t ns;
+        int r;
+
+        assert(u);
+
+        r = unit_get_cpu_usage_raw(u, &ns);
+        if (r < 0) {
+                u->cpuacct_usage_base = 0;
+                return r;
         }
 
+        u->cpuacct_usage_base = ns;
         return 0;
 }