#include "unit-name.h"
#include "fileio.h"
#include "special.h"
+#include "mkdir.h"
int cg_enumerate_processes(const char *controller, const char *path, FILE **_f) {
_cleanup_free_ char *fs = NULL;
return ret;
}
+int cg_migrate_recursive_fallback(
+ const char *cfrom,
+ const char *pfrom,
+ const char *cto,
+ const char *pto,
+ bool ignore_self,
+ bool rem) {
+
+ int r;
+
+ assert(cfrom);
+ assert(pfrom);
+ assert(cto);
+ assert(pto);
+
+ r = cg_migrate_recursive(cfrom, pfrom, cto, pto, ignore_self, rem);
+ if (r < 0) {
+ char prefix[strlen(pto) + 1];
+
+ /* This didn't work? Then let's try all prefixes of the destination */
+
+ PATH_FOREACH_PREFIX(prefix, pto) {
+ r = cg_migrate_recursive(cfrom, pfrom, cto, prefix, ignore_self, rem);
+ if (r >= 0)
+ break;
+ }
+ }
+
+ return 0;
+}
+
static const char *normalize_controller(const char *controller) {
assert(controller);
return r == -ENOENT ? 0 : r;
}
+int cg_create(const char *controller, const char *path) {
+ _cleanup_free_ char *fs = NULL;
+ int r;
+
+ r = cg_get_path_and_check(controller, path, NULL, &fs);
+ if (r < 0)
+ return r;
+
+ r = mkdir_parents(fs, 0755);
+ if (r < 0)
+ return r;
+
+ if (mkdir(fs, 0755) < 0) {
+
+ if (errno == EEXIST)
+ return 0;
+
+ return -errno;
+ }
+
+ return 1;
+}
+
+int cg_create_and_attach(const char *controller, const char *path, pid_t pid) {
+ int r, q;
+
+ assert(pid >= 0);
+
+ r = cg_create(controller, path);
+ if (r < 0)
+ return r;
+
+ q = cg_attach(controller, path, pid);
+ if (q < 0)
+ return q;
+
+ /* This does not remove the cgroup on failure */
+ return r;
+}
+
int cg_attach(const char *controller, const char *path, pid_t pid) {
_cleanup_free_ char *fs = NULL;
char c[DECIMAL_STR_MAX(pid_t) + 2];
return write_string_file(fs, c);
}
+int cg_attach_fallback(const char *controller, const char *path, pid_t pid) {
+ int r;
+
+ assert(controller);
+ assert(path);
+ assert(pid >= 0);
+
+ r = cg_attach(controller, path, pid);
+ if (r < 0) {
+ char prefix[strlen(path) + 1];
+
+ /* This didn't work? Then let's try all prefixes of
+ * the destination */
+
+ PATH_FOREACH_PREFIX(prefix, path) {
+ r = cg_attach(controller, prefix, pid);
+ if (r >= 0)
+ break;
+ }
+ }
+
+ return 0;
+}
+
int cg_set_group_access(
const char *controller,
const char *path,
return -EINVAL;
}
- u = strdup(e+1);
- if (!u) {
- free(t);
- return -ENOMEM;
- }
- if (!path_is_safe(u) ||
- !path_is_absolute(u)) {
- free(t);
- free(u);
- return -EINVAL;
- }
+ if (streq(e+1, "")) {
+ u = strdup("/");
+ if (!u) {
+ free(t);
+ return -ENOMEM;
+ }
+ } else {
+ u = strdup(e+1);
+ if (!u) {
+ free(t);
+ return -ENOMEM;
+ }
- path_kill_slashes(u);
+ if (!path_is_safe(u) ||
+ !path_is_absolute(u)) {
+ free(t);
+ free(u);
+ return -EINVAL;
+ }
+
+ path_kill_slashes(u);
+ }
if (controller)
*controller = t;
}
#define CONTROLLER_VALID \
- "0123456789" \
- "abcdefghijklmnopqrstuvwxyz" \
- "ABCDEFGHIJKLMNOPQRSTUVWXYZ" \
+ DIGITS LETTERS \
"_"
bool cg_controller_is_valid(const char *p, bool allow_named) {
"memory\0"
"devices\0";
-int cg_create_with_mask(CGroupControllerMask mask, const char *path) {
+int cg_create_everywhere(CGroupControllerMask supported, CGroupControllerMask mask, const char *path) {
CGroupControllerMask bit = 1;
const char *n;
int r;
/* Then, do the same in the other hierarchies */
NULSTR_FOREACH(n, mask_names) {
- if (bit & mask)
+ if (mask & bit)
cg_create(n, path);
- else
+ else if (supported & bit)
cg_trim(n, path, true);
bit <<= 1;
}
- return r;
+ return 0;
}
-int cg_attach_with_mask(CGroupControllerMask mask, const char *path, pid_t pid) {
+int cg_attach_everywhere(CGroupControllerMask supported, const char *path, pid_t pid) {
CGroupControllerMask bit = 1;
const char *n;
int r;
r = cg_attach(SYSTEMD_CGROUP_CONTROLLER, path, pid);
+ if (r < 0)
+ return r;
NULSTR_FOREACH(n, mask_names) {
- if (bit & mask)
- cg_attach(n, path, pid);
- else {
- char prefix[strlen(path) + 1], *slash;
-
- /* OK, this one is a bit harder... Now we need
- * to add to the closest parent cgroup we
- * can find */
- strcpy(prefix, path);
- while ((slash = strrchr(prefix, '/'))) {
- int q;
- *slash = 0;
-
- q = cg_attach(n, prefix, pid);
- if (q >= 0)
- break;
- }
- }
+ if (supported & bit)
+ cg_attach_fallback(n, path, pid);
bit <<= 1;
}
- return r;
+ return 0;
}
-int cg_attach_many_with_mask(CGroupControllerMask mask, const char *path, Set* pids) {
+int cg_attach_many_everywhere(CGroupControllerMask supported, const char *path, Set* pids) {
Iterator i;
void *pidp;
int r = 0;
SET_FOREACH(pidp, pids, i) {
pid_t pid = PTR_TO_LONG(pidp);
- int k;
+ int q;
- k = cg_attach_with_mask(mask, path, pid);
- if (k < 0)
- r = k;
+ q = cg_attach_everywhere(supported, path, pid);
+ if (q < 0)
+ r = q;
}
return r;
}
-int cg_migrate_with_mask(CGroupControllerMask mask, const char *from, const char *to) {
+int cg_migrate_everywhere(CGroupControllerMask supported, const char *from, const char *to) {
CGroupControllerMask bit = 1;
const char *n;
int r;
- if (path_equal(from, to))
- return 0;
-
- r = cg_migrate_recursive(SYSTEMD_CGROUP_CONTROLLER, from, SYSTEMD_CGROUP_CONTROLLER, to, false, true);
+ if (!path_equal(from, to)) {
+ r = cg_migrate_recursive(SYSTEMD_CGROUP_CONTROLLER, from, SYSTEMD_CGROUP_CONTROLLER, to, false, true);
+ if (r < 0)
+ return r;
+ }
NULSTR_FOREACH(n, mask_names) {
- if (bit & mask)
- cg_migrate_recursive(SYSTEMD_CGROUP_CONTROLLER, to, n, to, false, false);
- else {
- char prefix[strlen(to) + 1], *slash;
-
- strcpy(prefix, to);
- while ((slash = strrchr(prefix, '/'))) {
- int q;
-
- *slash = 0;
-
- q = cg_migrate_recursive(SYSTEMD_CGROUP_CONTROLLER, to, n, prefix, false, false);
- if (q >= 0)
- break;
- }
- }
+ if (supported & bit)
+ cg_migrate_recursive_fallback(SYSTEMD_CGROUP_CONTROLLER, to, n, to, false, false);
bit <<= 1;
}
- return r;
+ return 0;
}
-int cg_trim_with_mask(CGroupControllerMask mask, const char *path, bool delete_root) {
+int cg_trim_everywhere(CGroupControllerMask supported, const char *path, bool delete_root) {
CGroupControllerMask bit = 1;
const char *n;
int r;
return r;
NULSTR_FOREACH(n, mask_names) {
- if (bit & mask)
+ if (supported & bit)
cg_trim(n, path, delete_root);
bit <<= 1;
}
- return r;
+ return 0;
}
CGroupControllerMask cg_mask_supported(void) {