* tasks list, to properly handle forking processes */
if (!s) {
- s = allocated_set = set_new(trivial_hash_func, trivial_compare_func);
+ s = allocated_set = set_new(NULL);
if (!s)
return -ENOMEM;
}
if (kill(pid, sig) < 0) {
if (ret >= 0 && errno != ESRCH)
ret = -errno;
- } else if (ret == 0) {
-
+ } else {
if (sigcont)
kill(pid, SIGCONT);
- ret = 1;
+ if (ret == 0)
+ ret = 1;
}
done = false;
assert(sig >= 0);
if (!s) {
- s = allocated_set = set_new(trivial_hash_func, trivial_compare_func);
+ s = allocated_set = set_new(NULL);
if (!s)
return -ENOMEM;
}
assert(cto);
assert(pto);
- s = set_new(trivial_hash_func, trivial_compare_func);
+ s = set_new(NULL);
if (!s)
return -ENOMEM;
if (!t)
return -ENOMEM;
- path_kill_slashes(t);
-
- *fs = t;
+ *fs = path_kill_slashes(t);
return 0;
}
assert(p);
/* Check if this controller actually really exists */
- cc = alloca(sizeof("/sys/fs/cgroup/") + strlen(p));
+ cc = alloca(strlen("/sys/fs/cgroup/") + strlen(p) + 1);
strcpy(stpcpy(cc, "/sys/fs/cgroup/"), p);
if (access(cc, F_OK) < 0)
return -errno;
if (pid == 0)
pid = getpid();
- snprintf(c, sizeof(c), "%lu\n", (unsigned long) pid);
+ snprintf(c, sizeof(c), PID_FMT"\n", pid);
- return write_string_file(fs, c);
+ return write_string_file_no_create(fs, c);
}
int cg_attach_fallback(const char *controller, const char *path, pid_t pid) {
} else
controller = SYSTEMD_CGROUP_CONTROLLER;
- if (pid == 0)
- fs = "/proc/self/cgroup";
- else
- fs = procfs_file_alloca(pid, "cgroup");
+ fs = procfs_file_alloca(pid, "cgroup");
f = fopen(fs, "re");
if (!f)
cs = strlen(controller);
FOREACH_LINE(line, f, return -errno) {
- char *l, *p, *w, *e;
+ char *l, *p, *e;
size_t k;
- char *state;
+ const char *word, *state;
bool found = false;
truncate_nl(line);
*e = 0;
- FOREACH_WORD_SEPARATOR(w, k, l, ",", state) {
+ FOREACH_WORD_SEPARATOR(word, k, l, ",", state) {
- if (k == cs && memcmp(w, controller, cs) == 0) {
+ if (k == cs && memcmp(word, controller, cs) == 0) {
found = true;
break;
}
if (k == 5 + cs &&
- memcmp(w, "name=", 5) == 0 &&
- memcmp(w+5, controller, cs) == 0) {
+ memcmp(word, "name=", 5) == 0 &&
+ memcmp(word+5, controller, cs) == 0) {
found = true;
break;
}
sc = strstrip(contents);
if (sc[0] == 0) {
- r = write_string_file(fs, agent);
+ r = write_string_file_no_create(fs, agent);
if (r < 0)
return r;
} else if (!streq(sc, agent))
sc = strstrip(contents);
if (streq(sc, "0")) {
- r = write_string_file(fs, "1");
+ r = write_string_file_no_create(fs, "1");
if (r < 0)
return r;
if (r < 0)
return r;
- r = write_string_file(fs, "0");
+ r = write_string_file_no_create(fs, "0");
if (r < 0)
return r;
if (r < 0)
return r;
- r = write_string_file(fs, "");
+ r = write_string_file_no_create(fs, "");
if (r < 0)
return r;
if (!t)
return -ENOMEM;
- path_kill_slashes(t);
- *path = t;
+ *path = path_kill_slashes(t);
}
if (controller)
assert(path);
assert(result);
- /* First check if it already is a filesystem path */
+ /* First, check if it already is a filesystem path */
if (path_startswith(path, "/sys/fs/cgroup")) {
t = strdup(path);
if (!t)
return -ENOMEM;
- path_kill_slashes(t);
- *result = t;
+ *result = path_kill_slashes(t);
return 0;
}
- /* Otherwise treat it as cg spec */
+ /* Otherwise, treat it as cg spec */
r = cg_split_spec(path, &c, &p);
if (r < 0)
return r;
return 0;
}
-int cg_pid_get_path_shifted(pid_t pid, const char *root, char **cgroup) {
- _cleanup_free_ char *cg_root = NULL;
- char *cg_process, *p;
+int cg_shift_path(const char *cgroup, const char *root, const char **shifted) {
+ _cleanup_free_ char *rt = NULL;
+ char *p;
int r;
- assert(pid >= 0);
assert(cgroup);
+ assert(shifted);
if (!root) {
/* If the root was specified let's use that, otherwise
* let's determine it from PID 1 */
- r = cg_get_root_path(&cg_root);
+ r = cg_get_root_path(&rt);
if (r < 0)
return r;
- root = cg_root;
+ root = rt;
}
- r = cg_pid_get_path(SYSTEMD_CGROUP_CONTROLLER, pid, &cg_process);
+ p = path_startswith(cgroup, root);
+ if (p)
+ *shifted = p - 1;
+ else
+ *shifted = cgroup;
+
+ return 0;
+}
+
+int cg_pid_get_path_shifted(pid_t pid, const char *root, char **cgroup) {
+ _cleanup_free_ char *raw = NULL;
+ const char *c;
+ int r;
+
+ assert(pid >= 0);
+ assert(cgroup);
+
+ r = cg_pid_get_path(SYSTEMD_CGROUP_CONTROLLER, pid, &raw);
if (r < 0)
return r;
- p = path_startswith(cg_process, root);
- if (p) {
- char *c;
+ r = cg_shift_path(raw, root, &c);
+ if (r < 0)
+ return r;
- c = strdup(p - 1);
- free(cg_process);
+ if (c == raw) {
+ *cgroup = raw;
+ raw = NULL;
+ } else {
+ char *n;
- if (!c)
+ n = strdup(c);
+ if (!n)
return -ENOMEM;
- *cgroup = c;
- } else
- *cgroup = cg_process;
+ *cgroup = n;
+ }
return 0;
}
c = strndupa(cgroup, e - cgroup);
c = cg_unescape(c);
- if (!unit_name_is_valid(c, false))
+ if (!unit_name_is_valid(c, TEMPLATE_INVALID))
return -EINVAL;
s = strdup(c);
}
int cg_path_get_machine_name(const char *path, char **machine) {
- const char *e, *n, *x;
- char *s, *r;
- size_t l;
-
- assert(path);
- assert(machine);
-
- /* Skip slices, if there are any */
- e = skip_slices(path);
-
- n = strchrnul(e, '/');
- if (e == n)
- return -ENOENT;
-
- s = strndupa(e, n - e);
- s = cg_unescape(s);
-
- x = startswith(s, "machine-");
- if (!x)
- return -ENOENT;
- if (!endswith(x, ".scope"))
- return -ENOENT;
+ _cleanup_free_ char *u = NULL, *sl = NULL;
+ int r;
- l = strlen(x);
- if (l <= 6)
- return -ENOENT;
+ r = cg_path_get_unit(path, &u);
+ if (r < 0)
+ return r;
- r = strndup(x, l - 6);
- if (!r)
+ sl = strjoin("/run/systemd/machines/unit:", u, NULL);
+ if (!sl)
return -ENOMEM;
- *machine = r;
- return 0;
+ return readlink_malloc(sl, machine);
}
int cg_pid_get_machine_name(pid_t pid, char **machine) {
}
int cg_path_get_session(const char *path, char **session) {
- const char *e, *n, *x;
- char *s, *r;
- size_t l;
+ const char *e, *n, *x, *y;
+ char *s;
assert(path);
- assert(session);
/* Skip slices, if there are any */
e = skip_slices(path);
x = startswith(s, "session-");
if (!x)
return -ENOENT;
- if (!endswith(x, ".scope"))
+ y = endswith(x, ".scope");
+ if (!y || x == y)
return -ENOENT;
- l = strlen(x);
- if (l <= 6)
- return -ENOENT;
+ if (session) {
+ char *r;
- r = strndup(x, l - 6);
- if (!r)
- return -ENOMEM;
+ r = strndup(x, y - x);
+ if (!r)
+ return -ENOMEM;
+
+ *session = r;
+ }
- *session = r;
return 0;
}
_cleanup_free_ char *cgroup = NULL;
int r;
- assert(session);
-
r = cg_pid_get_path_shifted(pid, NULL, &cgroup);
if (r < 0)
return r;
assert(unit);
assert(ret);
- if (!unit_name_is_valid(unit, false))
+ if (!unit_name_is_valid(unit, TEMPLATE_INVALID))
return -EINVAL;
if (!endswith(unit, ".slice"))
strcpy(stpncpy(n, p, dash - p), ".slice");
- if (!unit_name_is_valid(n, false))
+ if (!unit_name_is_valid(n, TEMPLATE_INVALID))
return -EINVAL;
escaped = cg_escape(n);
if (r < 0)
return r;
- return write_string_file(p, value);
+ return write_string_file_no_create(p, value);
}
static const char mask_names[] =
return r;
}
-int cg_migrate_everywhere(CGroupControllerMask supported, const char *from, const char *to) {
+int cg_migrate_everywhere(CGroupControllerMask supported, const char *from, const char *to, cg_migrate_callback_t to_callback, void *userdata) {
CGroupControllerMask bit = 1;
const char *n;
int r;
}
NULSTR_FOREACH(n, mask_names) {
- if (supported & bit)
- cg_migrate_recursive_fallback(SYSTEMD_CGROUP_CONTROLLER, to, n, to, false, false);
+ if (supported & bit) {
+ const char *p = NULL;
+
+ if (to_callback)
+ p = to_callback(bit, userdata);
+
+ if (!p)
+ p = to;
+
+ cg_migrate_recursive_fallback(SYSTEMD_CGROUP_CONTROLLER, to, n, p, false, false);
+ }
bit <<= 1;
}