]> git.ipfire.org Git - thirdparty/systemd.git/blobdiff - src/shared/condition.c
strv: make iterator in STRV_FOREACH() declaread in the loop
[thirdparty/systemd.git] / src / shared / condition.c
index 63bdc38a490a4f366d06bf44375c5c06acada05f..0a4072c9bef58bb645657d40df19d1aae9d60aaa 100644 (file)
 #include "psi-util.h"
 #include "selinux-util.h"
 #include "smack-util.h"
+#include "special.h"
 #include "stat-util.h"
 #include "string-table.h"
 #include "string-util.h"
 #include "tomoyo-util.h"
+#include "udev-util.h"
 #include "uid-alloc-range.h"
 #include "user-util.h"
-#include "util.h"
 #include "virt.h"
 
 Condition* condition_new(ConditionType type, const char *parameter, bool trigger, bool negate) {
@@ -88,9 +89,7 @@ Condition* condition_free(Condition *c) {
 }
 
 Condition* condition_free_list_type(Condition *head, ConditionType type) {
-        Condition *c, *n;
-
-        LIST_FOREACH_SAFE(conditions, c, n, head)
+        LIST_FOREACH(conditions, c, head)
                 if (type < 0 || c->type == type) {
                         LIST_REMOVE(conditions, head, c);
                         condition_free(c);
@@ -828,7 +827,6 @@ static int condition_test_first_boot(Condition *c, char **env) {
 
 static int condition_test_environment(Condition *c, char **env) {
         bool equal;
-        char **i;
 
         assert(c);
         assert(c->parameter);
@@ -992,14 +990,14 @@ static int condition_test_psi(Condition *c, char **env) {
         if (r == 1) {
                 pressure_path = path_join("/proc/pressure", pressure_type);
                 if (!pressure_path)
-                        return log_oom();
+                        return log_oom_debug();
 
                 value = first;
         } else {
                 const char *controller = strjoina(pressure_type, ".pressure");
-                _cleanup_free_ char *slice_path = NULL;
+                _cleanup_free_ char *slice_path = NULL, *root_scope = NULL;
                 CGroupMask mask, required_mask;
-                char *slice;
+                char *slice, *e;
 
                 required_mask = c->type == CONDITION_MEMORY_PRESSURE ? CGROUP_MASK_MEMORY :
                                 c->type == CONDITION_CPU_PRESSURE ? CGROUP_MASK_CPU :
@@ -1030,6 +1028,26 @@ static int condition_test_psi(Condition *c, char **env) {
                 if (r < 0)
                         return log_debug_errno(r, "Cannot determine slice \"%s\" cgroup path: %m", slice);
 
+                /* We might be running under the user manager, so get the root path and prefix it accordingly. */
+                r = cg_pid_get_path(SYSTEMD_CGROUP_CONTROLLER, getpid_cached(), &root_scope);
+                if (r < 0)
+                        return log_debug_errno(r, "Failed to get root cgroup path: %m");
+
+                /* Drop init.scope, we want the parent. We could get an empty or / path, but that's fine,
+                 * just skip it in that case. */
+                e = endswith(root_scope, "/" SPECIAL_INIT_SCOPE);
+                if (e)
+                        *e = 0;
+                if (!empty_or_root(root_scope)) {
+                        _cleanup_free_ char *slice_joined = NULL;
+
+                        slice_joined = path_join(root_scope, slice_path);
+                        if (!slice_joined)
+                                return log_oom_debug();
+
+                        free_and_replace(slice_path, slice_joined);
+                }
+
                 r = cg_get_path(SYSTEMD_CGROUP_CONTROLLER, slice_path, controller, &pressure_path);
                 if (r < 0)
                         return log_debug_errno(r, "Error getting cgroup pressure path from %s: %m", slice_path);
@@ -1150,7 +1168,6 @@ bool condition_test_list(
                 condition_test_logger_t logger,
                 void *userdata) {
 
-        Condition *c;
         int triggered = -1;
 
         assert(!!logger == !!to_string);
@@ -1213,8 +1230,6 @@ void condition_dump(Condition *c, FILE *f, const char *prefix, condition_to_stri
 }
 
 void condition_dump_list(Condition *first, FILE *f, const char *prefix, condition_to_string_t to_string) {
-        Condition *c;
-
         LIST_FOREACH(conditions, c, first)
                 condition_dump(c, f, prefix, to_string);
 }