diff --git a/man/systemd.resource-control.xml b/man/systemd.resource-control.xml index fe875a81c3d..1142ad7758f 100644 --- a/man/systemd.resource-control.xml +++ b/man/systemd.resource-control.xml @@ -1101,10 +1101,10 @@ DeviceAllow=/dev/loop-control only respect these extended attributes if the unit's cgroup is owned by root. When calculating candidates to relieve memory pressure, systemd-oomd - will only respect these extended attributes if the unit's cgroup owner, and the - owner of the monitored ancestor cgroup are the same. For example, if systemd-oomd - is calculating candidates for -.slice, then extended attributes set - on descendants of /user.slice/user-1000.slice/user@1000.service/ + will only respect these extended attributes if the unit's cgroup is owned by root, or if the + unit's cgroup owner, and the owner of the monitored ancestor cgroup are the same. For example, + if systemd-oomd is calculating candidates for -.slice, + then extended attributes set on descendants of /user.slice/user-1000.slice/user@1000.service/ will be ignored because the descendants are owned by UID 1000, and -.slice is owned by UID 0. But, if calculating candidates for /user.slice/user-1000.slice/user@1000.service/, then extended attributes set diff --git a/src/oom/oomd-util.c b/src/oom/oomd-util.c index 70a1dc941e6..7291e044eb1 100644 --- a/src/oom/oomd-util.c +++ b/src/oom/oomd-util.c @@ -145,7 +145,7 @@ bool oomd_swap_free_below(const OomdSystemContext *ctx, int threshold_permyriad) } int oomd_fetch_cgroup_oom_preference(OomdCGroupContext *ctx, const char *prefix) { - uid_t uid, prefix_uid; + uid_t uid; int r; assert(ctx); @@ -160,28 +160,34 @@ int oomd_fetch_cgroup_oom_preference(OomdCGroupContext *ctx, const char *prefix) if (r < 0) return log_debug_errno(r, "Failed to get owner/group from %s: %m", ctx->path); - r = cg_get_owner(SYSTEMD_CGROUP_CONTROLLER, prefix, &prefix_uid); - if (r < 0) - return log_debug_errno(r, "Failed to get owner/group from %s: %m", ctx->path); + if (uid != 0) { + uid_t prefix_uid; - if (uid == prefix_uid || uid == 0) { - /* Ignore most errors when reading the xattr since it is usually unset and cgroup xattrs are only used - * as an optional feature of systemd-oomd (and the system might not even support them). */ - r = cg_get_xattr_bool(SYSTEMD_CGROUP_CONTROLLER, ctx->path, "user.oomd_avoid"); - if (r == -ENOMEM) - return log_oom_debug(); - if (r < 0 && !ERRNO_IS_XATTR_ABSENT(r)) - log_debug_errno(r, "Failed to get xattr user.oomd_avoid, ignoring: %m"); - ctx->preference = r > 0 ? MANAGED_OOM_PREFERENCE_AVOID : ctx->preference; + r = cg_get_owner(SYSTEMD_CGROUP_CONTROLLER, prefix, &prefix_uid); + if (r < 0) + return log_debug_errno(r, "Failed to get owner/group from %s: %m", prefix); - r = cg_get_xattr_bool(SYSTEMD_CGROUP_CONTROLLER, ctx->path, "user.oomd_omit"); - if (r == -ENOMEM) - return log_oom_debug(); - if (r < 0 && !ERRNO_IS_XATTR_ABSENT(r)) - log_debug_errno(r, "Failed to get xattr user.oomd_omit, ignoring: %m"); - ctx->preference = r > 0 ? MANAGED_OOM_PREFERENCE_OMIT : ctx->preference; - } else - ctx->preference = MANAGED_OOM_PREFERENCE_NONE; + if (uid != prefix_uid) { + ctx->preference = MANAGED_OOM_PREFERENCE_NONE; + return 0; + } + } + + /* Ignore most errors when reading the xattr since it is usually unset and cgroup xattrs are only used + * as an optional feature of systemd-oomd (and the system might not even support them). */ + r = cg_get_xattr_bool(SYSTEMD_CGROUP_CONTROLLER, ctx->path, "user.oomd_avoid"); + if (r == -ENOMEM) + return log_oom_debug(); + if (r < 0 && !ERRNO_IS_XATTR_ABSENT(r)) + log_debug_errno(r, "Failed to get xattr user.oomd_avoid, ignoring: %m"); + ctx->preference = r > 0 ? MANAGED_OOM_PREFERENCE_AVOID : ctx->preference; + + r = cg_get_xattr_bool(SYSTEMD_CGROUP_CONTROLLER, ctx->path, "user.oomd_omit"); + if (r == -ENOMEM) + return log_oom_debug(); + if (r < 0 && !ERRNO_IS_XATTR_ABSENT(r)) + log_debug_errno(r, "Failed to get xattr user.oomd_omit, ignoring: %m"); + ctx->preference = r > 0 ? MANAGED_OOM_PREFERENCE_OMIT : ctx->preference; return 0; } diff --git a/src/oom/oomd-util.h b/src/oom/oomd-util.h index 7fd9e92109a..a758d5589bf 100644 --- a/src/oom/oomd-util.h +++ b/src/oom/oomd-util.h @@ -109,9 +109,10 @@ static inline int compare_swap_usage(OomdCGroupContext * const *c1, OomdCGroupCo * Returns the number of sorted items; negative on error. */ int oomd_sort_cgroup_contexts(Hashmap *h, oomd_compare_t compare_func, const char *prefix, OomdCGroupContext ***ret); -/* If the cgroups represented by `ctx` and `prefix` are owned by the same user, - * then set `ctx->preference` using the `user.oomd_avoid` and `user.oomd_omit` - * xattrs. Otherwise, set `ctx->preference` to MANAGED_OOM_PREFERENCE_NONE. +/* If the the cgroup is owned by root, or the cgroups represented by `ctx` and + * `prefix` are owned by the same user, then set `ctx->preference` using the + * `user.oomd_avoid` and `user.oomd_omit` xattrs. Otherwise, set + * `ctx->preference` to MANAGED_OOM_PREFERENCE_NONE. * * If `prefix` is NULL or the empty string, it is treated as root. If `prefix` * does not specify an ancestor cgroup of `ctx`, -EINVAL is returned. Returns