if (r < 0 && errno != ENOENT)
return -errno;
- if (streq(controller, SYSTEMD_CGROUP_CONTROLLER) && cg_hybrid_unified()) {
- r = cg_rmdir(SYSTEMD_CGROUP_CONTROLLER_LEGACY, path);
- if (r < 0)
- log_warning_errno(r, "Failed to remove compat systemd cgroup %s: %m", path);
- }
-
return 0;
}
* just cuts off the name= prefixed used for named
* hierarchies, if it is specified. */
- if (streq(controller, SYSTEMD_CGROUP_CONTROLLER)) {
- if (cg_hybrid_unified())
- controller = SYSTEMD_CGROUP_CONTROLLER_HYBRID;
- else
- controller = SYSTEMD_CGROUP_CONTROLLER_LEGACY;
- }
-
e = startswith(controller, "name=");
if (e)
return e;
int cg_trim(const char *controller, const char *path, bool delete_root) {
_cleanup_free_ char *fs = NULL;
- int r = 0, q;
+ int r = 0;
assert(path);
return -errno;
}
- if (streq(controller, SYSTEMD_CGROUP_CONTROLLER) && cg_hybrid_unified()) {
- q = cg_trim(SYSTEMD_CGROUP_CONTROLLER_LEGACY, path, delete_root);
- if (q < 0)
- log_warning_errno(q, "Failed to trim compat systemd cgroup %s: %m", path);
- }
-
return r;
}
return -errno;
}
- if (streq(controller, SYSTEMD_CGROUP_CONTROLLER) && cg_hybrid_unified()) {
- r = cg_create(SYSTEMD_CGROUP_CONTROLLER_LEGACY, path);
- if (r < 0)
- log_warning_errno(r, "Failed to create compat systemd cgroup %s: %m", path);
- }
-
return 1;
}
xsprintf(c, PID_FMT "\n", pid);
- r = write_string_file(fs, c, 0);
- if (r < 0)
- return r;
-
- if (streq(controller, SYSTEMD_CGROUP_CONTROLLER) && cg_hybrid_unified()) {
- r = cg_attach(SYSTEMD_CGROUP_CONTROLLER_LEGACY, path, pid);
- if (r < 0)
- log_warning_errno(r, "Failed to attach %d to compat systemd cgroup %s: %m", pid, path);
- }
-
- return 0;
+ return write_string_file(fs, c, 0);
}
int cg_attach_fallback(const char *controller, const char *path, pid_t pid) {
if (r < 0)
return r;
- r = chmod_and_chown(fs, mode, uid, gid);
- if (r < 0)
- return r;
-
- if (streq(controller, SYSTEMD_CGROUP_CONTROLLER) && cg_hybrid_unified()) {
- r = cg_set_group_access(SYSTEMD_CGROUP_CONTROLLER_LEGACY, path, mode, uid, gid);
- if (r < 0)
- log_warning_errno(r, "Failed to set group access on compat systemd cgroup %s: %m", path);
- }
-
- return 0;
+ return chmod_and_chown(fs, mode, uid, gid);
}
int cg_set_task_access(
if (r < 0)
return r;
- if (!cg_unified(controller)) {
- /* Compatibility, Always keep values for "tasks" in sync with
- * "cgroup.procs" */
- if (cg_get_path(controller, path, "tasks", &procs) >= 0)
- (void) chmod_and_chown(procs, mode, uid, gid);
- }
+ if (cg_unified(controller))
+ return 0;
- if (streq(controller, SYSTEMD_CGROUP_CONTROLLER) && cg_hybrid_unified()) {
- r = cg_set_task_access(SYSTEMD_CGROUP_CONTROLLER_LEGACY, path, mode, uid, gid);
- if (r < 0)
- log_warning_errno(r, "Failed to set task access on compat systemd cgroup %s: %m", path);
- }
+ /* Compatibility, Always keep values for "tasks" in sync with
+ * "cgroup.procs" */
+ if (cg_get_path(controller, path, "tasks", &procs) >= 0)
+ (void) chmod_and_chown(procs, mode, uid, gid);
return 0;
}
int cg_pid_get_path(const char *controller, pid_t pid, char **path) {
_cleanup_fclose_ FILE *f = NULL;
char line[LINE_MAX];
- const char *fs, *controller_str;
+ const char *fs;
size_t cs = 0;
bool unified;
controller = SYSTEMD_CGROUP_CONTROLLER;
unified = cg_unified(controller);
- if (!unified) {
- if (streq(controller, SYSTEMD_CGROUP_CONTROLLER))
- controller_str = SYSTEMD_CGROUP_CONTROLLER_LEGACY;
- else
- controller_str = controller;
-
- cs = strlen(controller_str);
- }
+ if (!unified)
+ cs = strlen(controller);
fs = procfs_file_alloca(pid, "cgroup");
log_debug_elogind("Searching for PID %u in \"%s\" (controller \"%s\")",
*e = 0;
FOREACH_WORD_SEPARATOR(word, k, l, ",", state) {
- if (k == cs && memcmp(word, controller_str, cs) == 0) {
+ if (k == cs && memcmp(word, controller, cs) == 0) {
found = true;
break;
}
if (!p)
return false;
- if (streq(p, SYSTEMD_CGROUP_CONTROLLER))
- return true;
-
s = startswith(p, "name=");
if (s)
p = s;
if (F_TYPE_EQUAL(fs.f_type, CGROUP2_SUPER_MAGIC))
unified_cache = CGROUP_UNIFIED_ALL;
else if (F_TYPE_EQUAL(fs.f_type, TMPFS_MAGIC)) {
- if (statfs("/sys/fs/cgroup/unified/", &fs) == 0 &&
- F_TYPE_EQUAL(fs.f_type, CGROUP2_SUPER_MAGIC))
- unified_cache = CGROUP_UNIFIED_SYSTEMD;
- else {
- if (statfs("/sys/fs/cgroup/systemd/", &fs) < 0)
- return -errno;
- if (!F_TYPE_EQUAL(fs.f_type, CGROUP_SUPER_MAGIC))
- return -ENOMEDIUM;
- unified_cache = CGROUP_UNIFIED_NONE;
- }
+ if (statfs("/sys/fs/cgroup/systemd/", &fs) < 0)
+ return -errno;
+
+ unified_cache = F_TYPE_EQUAL(fs.f_type, CGROUP2_SUPER_MAGIC) ?
+ CGROUP_UNIFIED_SYSTEMD : CGROUP_UNIFIED_NONE;
} else
return -ENOMEDIUM;
#else
}
#if 0 /// UNNEEDED by elogind
-bool cg_hybrid_unified(void) {
-
- assert(cg_update_unified() >= 0);
-
- return unified_cache == CGROUP_UNIFIED_SYSTEMD;
-}
-
int cg_unified_flush(void) {
unified_cache = CGROUP_UNIFIED_UNKNOWN;
/* The meaning of the kernel option is reversed wrt. to the return value
* of this function, hence the negation. */
return (wanted = r > 0 ? !b : false);
+ return (wanted = r > 0 ? b : false);
+}
+
+bool cg_is_legacy_systemd_controller_wanted(void) {
+ return cg_is_legacy_wanted() && !cg_is_unified_systemd_controller_wanted();
}
#endif // 0
static int whitelist_device(const char *path, const char *node, const char *acc) {
char buf[2+DECIMAL_STR_MAX(dev_t)*2+2+4];
struct stat st;
+ bool ignore_notfound;
int r;
assert(path);
assert(acc);
+ if (node[0] == '-') {
+ /* Non-existent paths starting with "-" must be silently ignored */
+ node++;
+ ignore_notfound = true;
+ } else
+ ignore_notfound = false;
+
if (stat(node, &st) < 0) {
- log_warning("Couldn't stat device %s", node);
- return -errno;
+ if (errno == ENOENT && ignore_notfound)
+ return 0;
+
+ return log_warning_errno(errno, "Couldn't stat device %s: %m", node);
}
if (!S_ISCHR(st.st_mode) && !S_ISBLK(st.st_mode)) {
bool has_weight = cgroup_context_has_cpu_weight(c);
bool has_shares = cgroup_context_has_cpu_shares(c);
- if (cg_all_unified() > 0) {
+ if (cg_all_unified()) {
uint64_t weight;
if (has_weight)
}
if ((mask & CGROUP_MASK_MEMORY) && !is_root) {
- if (cg_all_unified() > 0) {
+ if (cg_all_unified()) {
uint64_t max;
uint64_t swap_max = CGROUP_LIMIT_MAX;
"/dev/pts/ptmx\0" "rw\0" /* /dev/pts/ptmx may not be duplicated, but accessed */
/* Allow /run/elogind/inaccessible/{chr,blk} devices for mapping InaccessiblePaths */
/* Allow /run/systemd/inaccessible/{chr,blk} devices for mapping InaccessiblePaths */
- "/run/systemd/inaccessible/chr\0" "rwm\0"
- "/run/systemd/inaccessible/blk\0" "rwm\0";
+ "-/run/systemd/inaccessible/chr\0" "rwm\0"
+ "-/run/systemd/inaccessible/blk\0" "rwm\0";
const char *x, *y;
e = unit_get_exec_context(u);
if (!e ||
exec_context_maintains_privileges(e) ||
- cg_all_unified() > 0)
+ cg_all_unified())
return _CGROUP_MASK_ALL;
}
return 0;
/* Only applies to the unified hierarchy */
- r = cg_unified(SYSTEMD_CGROUP_CONTROLLER);
- if (r < 0)
- return log_unit_error_errno(u, r, "Failed detect whether the unified hierarchy is used: %m");
- if (r == 0)
+ if (!cg_unified(SYSTEMD_CGROUP_CONTROLLER))
return 0;
/* Don't watch the root slice, it's pointless. */
if (!u->cgroup_path)
return -ENOENT;
- if (cg_unified(SYSTEMD_CGROUP_CONTROLLER) > 0) /* On unified we can use proper notifications */
+ if (cg_unified(SYSTEMD_CGROUP_CONTROLLER)) /* On unified we can use proper notifications */
return 0;
return unit_watch_pids_in_path(u, u->cgroup_path);
int manager_setup_cgroup(Manager *m) {
_cleanup_free_ char *path = NULL;
CGroupController c;
- int r, all_unified, systemd_unified;
+ int r;
char *e;
assert(m);
if (r < 0)
return log_error_errno(r, "Cannot find cgroup mount point: %m");
- all_unified = cg_all_unified();
- systemd_unified = cg_unified(SYSTEMD_CGROUP_CONTROLLER);
-
- if (all_unified < 0 || systemd_unified < 0)
- return log_error_errno(all_unified < 0 ? all_unified : systemd_unified,
- "Couldn't determine if we are running in the unified hierarchy: %m");
+ r = cg_unified_flush();
+ if (r < 0)
+ return log_error_errno(r, "Couldn't determine if we are running in the unified hierarchy: %m");
- if (all_unified > 0)
+ if (cg_all_unified())
log_debug("Unified cgroup hierarchy is located at %s.", path);
- else if (systemd_unified > 0)
+ else if (cg_unified(SYSTEMD_CGROUP_CONTROLLER))
log_debug("Unified cgroup hierarchy is located at %s. Controllers are on legacy hierarchies.", path);
else
log_debug("Using cgroup controller " SYSTEMD_CGROUP_CONTROLLER ". File system hierarchy is at %s.", path);
const char *scope_path;
/* 3. Install agent */
- if (systemd_unified) {
+ if (cg_unified(SYSTEMD_CGROUP_CONTROLLER)) {
/* In the unified hierarchy we can get
* cgroup empty notifications via inotify. */
return log_error_errno(errno, "Failed to open pin file: %m");
/* 6. Always enable hierarchical support if it exists... */
- if (!all_unified)
+ if (!cg_all_unified())
(void) cg_set_attribute("memory", "/", "memory.use_hierarchy", "1");
}
if ((u->cgroup_realized_mask & CGROUP_MASK_MEMORY) == 0)
return -ENODATA;
- if (cg_all_unified() <= 0)
+ if (!cg_all_unified())
r = cg_get_attribute("memory", u->cgroup_path, "memory.usage_in_bytes", &v);
else
r = cg_get_attribute("memory", u->cgroup_path, "memory.current", &v);
if (!u->cgroup_path)
return -ENODATA;
- if (cg_all_unified() > 0) {
+ if (cg_all_unified()) {
const char *keys[] = { "usage_usec", NULL };
_cleanup_free_ char *val = NULL;
uint64_t us;