summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/core/unit.c26
-rw-r--r--src/journal/journald-server.c162
-rw-r--r--src/login/logind-session.c13
-rw-r--r--src/login/logind-user.c12
-rw-r--r--src/login/sd-login.c35
-rw-r--r--src/nspawn/nspawn.c18
-rw-r--r--src/shared/cgroup-util.c123
-rw-r--r--src/shared/cgroup-util.h5
-rw-r--r--src/test/test-cgroup-util.c40
9 files changed, 271 insertions, 163 deletions
diff --git a/src/core/unit.c b/src/core/unit.c
index 2525f49980..5834009445 100644
--- a/src/core/unit.c
+++ b/src/core/unit.c
@@ -1810,14 +1810,13 @@ static const char *resolve_template(Unit *u, const char *name, const char*path,
if (u->instance)
s = unit_name_replace_instance(name, u->instance);
else {
- char *i;
+ _cleanup_free_ char *i = NULL;
i = unit_name_to_prefix(u->id);
if (!i)
return NULL;
s = unit_name_replace_instance(name, i);
- free(i);
}
if (!s)
@@ -1972,15 +1971,30 @@ char *unit_default_cgroup_path(Unit *u) {
assert(u);
if (u->instance) {
- _cleanup_free_ char *t = NULL;
+ _cleanup_free_ char *t = NULL, *escaped_template = NULL, *escaped_instance = NULL;
t = unit_name_template(u->id);
if (!t)
return NULL;
- return strjoin(u->manager->cgroup_hierarchy, "/", t, "/", u->instance, NULL);
- } else
- return strjoin(u->manager->cgroup_hierarchy, "/", u->id, NULL);
+ escaped_template = cg_escape(t);
+ if (!escaped_template)
+ return NULL;
+
+ escaped_instance = cg_escape(u->id);
+ if (!escaped_instance)
+ return NULL;
+
+ return strjoin(u->manager->cgroup_hierarchy, "/", escaped_template, "/", escaped_instance, NULL);
+ } else {
+ _cleanup_free_ char *escaped = NULL;
+
+ escaped = cg_escape(u->id);
+ if (!escaped)
+ return NULL;
+
+ return strjoin(u->manager->cgroup_hierarchy, "/", escaped, NULL);
+ }
}
int unit_add_cgroup_from_text(Unit *u, const char *name, bool overwrite, CGroupBonding **ret) {
diff --git a/src/journal/journald-server.c b/src/journal/journald-server.c
index 7e7b379df8..4134e9fc67 100644
--- a/src/journal/journald-server.c
+++ b/src/journal/journald-server.c
@@ -31,10 +31,6 @@
#include <systemd/sd-messages.h>
#include <systemd/sd-daemon.h>
-#ifdef HAVE_LOGIND
-#include <systemd/sd-login.h>
-#endif
-
#include "fileio.h"
#include "mkdir.h"
#include "hashmap.h"
@@ -505,26 +501,26 @@ static void dispatch_message_real(
const char *label, size_t label_len,
const char *unit_id) {
- char pid[sizeof("_PID=") + DECIMAL_STR_MAX(ucred->pid)],
- uid[sizeof("_UID=") + DECIMAL_STR_MAX(ucred->uid)],
- gid[sizeof("_GID=") + DECIMAL_STR_MAX(ucred->gid)],
+ char pid[sizeof("_PID=") + DECIMAL_STR_MAX(pid_t)],
+ uid[sizeof("_UID=") + DECIMAL_STR_MAX(uid_t)],
+ gid[sizeof("_GID=") + DECIMAL_STR_MAX(gid_t)],
+ owner_uid[sizeof("_SYSTEMD_OWNER_UID=") + DECIMAL_STR_MAX(uid_t)],
source_time[sizeof("_SOURCE_REALTIME_TIMESTAMP=") + DECIMAL_STR_MAX(usec_t)],
boot_id[sizeof("_BOOT_ID=") + 32] = "_BOOT_ID=",
machine_id[sizeof("_MACHINE_ID=") + 32] = "_MACHINE_ID=";
-
- _cleanup_free_ char *comm = NULL, *cmdline = NULL, *hostname = NULL,
- *exe = NULL, *cgroup = NULL, *session = NULL,
- *owner_uid = NULL, *unit = NULL, *selinux_context = NULL;
-
-#ifdef HAVE_AUDIT
- _cleanup_free_ char *audit_session = NULL, *audit_loginuid = NULL;
-#endif
-
+ char *comm, *exe, *cmdline, *cgroup, *session, *unit, *selinux_context, *hostname;
sd_id128_t id;
int r;
- char *t;
+ char *t, *c;
uid_t realuid = 0, owner = 0, journal_uid;
bool owner_valid = false;
+#ifdef HAVE_AUDIT
+ char audit_session[sizeof("_AUDIT_SESSION=") + DECIMAL_STR_MAX(uint32_t)],
+ audit_loginuid[sizeof("_AUDIT_LOGINUID=") + DECIMAL_STR_MAX(uid_t)];
+
+ uint32_t audit;
+ uid_t loginuid;
+#endif
assert(s);
assert(iovec);
@@ -532,130 +528,111 @@ static void dispatch_message_real(
assert(n + N_IOVEC_META_FIELDS <= m);
if (ucred) {
-#ifdef HAVE_AUDIT
- uint32_t audit;
- uid_t loginuid;
-#endif
-
realuid = ucred->uid;
- snprintf(pid, sizeof(pid) - 1, "_PID=%lu", (unsigned long) ucred->pid);
- char_array_0(pid);
+ sprintf(pid, "_PID=%lu", (unsigned long) ucred->pid);
IOVEC_SET_STRING(iovec[n++], pid);
- snprintf(uid, sizeof(uid) - 1, "_UID=%lu", (unsigned long) ucred->uid);
- char_array_0(uid);
+ sprintf(uid, "_UID=%lu", (unsigned long) ucred->uid);
IOVEC_SET_STRING(iovec[n++], uid);
- snprintf(gid, sizeof(gid) - 1, "_GID=%lu", (unsigned long) ucred->gid);
- char_array_0(gid);
+ sprintf(gid, "_GID=%lu", (unsigned long) ucred->gid);
IOVEC_SET_STRING(iovec[n++], gid);
r = get_process_comm(ucred->pid, &t);
if (r >= 0) {
- comm = strappend("_COMM=", t);
+ comm = strappenda("_COMM=", t);
free(t);
-
- if (comm)
- IOVEC_SET_STRING(iovec[n++], comm);
+ IOVEC_SET_STRING(iovec[n++], comm);
}
r = get_process_exe(ucred->pid, &t);
if (r >= 0) {
- exe = strappend("_EXE=", t);
+ exe = strappenda("_EXE=", t);
free(t);
-
- if (exe)
- IOVEC_SET_STRING(iovec[n++], exe);
+ IOVEC_SET_STRING(iovec[n++], exe);
}
r = get_process_cmdline(ucred->pid, 0, false, &t);
if (r >= 0) {
- cmdline = strappend("_CMDLINE=", t);
+ cmdline = strappenda("_CMDLINE=", t);
free(t);
-
- if (cmdline)
- IOVEC_SET_STRING(iovec[n++], cmdline);
+ IOVEC_SET_STRING(iovec[n++], cmdline);
}
#ifdef HAVE_AUDIT
r = audit_session_from_pid(ucred->pid, &audit);
- if (r >= 0)
- if (asprintf(&audit_session, "_AUDIT_SESSION=%lu", (unsigned long) audit) >= 0)
- IOVEC_SET_STRING(iovec[n++], audit_session);
+ if (r >= 0) {
+ sprintf(audit_session, "_AUDIT_SESSION=%lu", (unsigned long) audit);
+ IOVEC_SET_STRING(iovec[n++], audit_session);
+ }
r = audit_loginuid_from_pid(ucred->pid, &loginuid);
- if (r >= 0)
- if (asprintf(&audit_loginuid, "_AUDIT_LOGINUID=%lu", (unsigned long) loginuid) >= 0)
- IOVEC_SET_STRING(iovec[n++], audit_loginuid);
-#endif
-
- r = cg_pid_get_path(NULL, ucred->pid, &t);
if (r >= 0) {
- cgroup = strappend("_SYSTEMD_CGROUP=", t);
- free(t);
-
- if (cgroup)
- IOVEC_SET_STRING(iovec[n++], cgroup);
+ sprintf(audit_loginuid, "_AUDIT_LOGINUID=%lu", (unsigned long) loginuid);
+ IOVEC_SET_STRING(iovec[n++], audit_loginuid);
}
+#endif
-#ifdef HAVE_LOGIND
- r = cg_pid_get_session(ucred->pid, &t);
+ r = cg_pid_get_path_shifted(ucred->pid, NULL, &c);
if (r >= 0) {
- session = strappend("_SYSTEMD_SESSION=", t);
- free(t);
+ cgroup = strappenda("_SYSTEMD_CGROUP=", c);
+ IOVEC_SET_STRING(iovec[n++], cgroup);
- if (session)
+ r = cg_path_get_session(c, &t);
+ if (r >= 0) {
+ session = strappenda("_SYSTEMD_SESSION=", t);
+ free(t);
IOVEC_SET_STRING(iovec[n++], session);
- }
+ }
- if (sd_pid_get_owner_uid(ucred->pid, &owner) >= 0) {
- owner_valid = true;
- if (asprintf(&owner_uid, "_SYSTEMD_OWNER_UID=%lu", (unsigned long) owner) >= 0)
+ if (cg_path_get_owner_uid(c, &owner) >= 0) {
+ owner_valid = true;
+
+ sprintf(owner_uid, "_SYSTEMD_OWNER_UID=%lu", (unsigned long) owner);
IOVEC_SET_STRING(iovec[n++], owner_uid);
- }
-#endif
+ }
- if (cg_pid_get_unit(ucred->pid, &t) >= 0) {
- unit = strappend("_SYSTEMD_UNIT=", t);
- free(t);
- } else if (cg_pid_get_user_unit(ucred->pid, &t) >= 0) {
- unit = strappend("_SYSTEMD_USER_UNIT=", t);
- free(t);
- } else if (unit_id) {
- if (session)
- unit = strappend("_SYSTEMD_USER_UNIT=", unit_id);
- else
- unit = strappend("_SYSTEMD_UNIT=", unit_id);
+ if (cg_path_get_unit(c, &t) >= 0) {
+ unit = strappenda("_SYSTEMD_UNIT=", t);
+ free(t);
+ } else if (cg_path_get_user_unit(c, &t) >= 0) {
+ unit = strappenda("_SYSTEMD_USER_UNIT=", t);
+ free(t);
+ } else if (unit_id) {
+ if (session)
+ unit = strappenda("_SYSTEMD_USER_UNIT=", unit_id);
+ else
+ unit = strappenda("_SYSTEMD_UNIT=", unit_id);
+ } else
+ unit = NULL;
+
+ if (unit)
+ IOVEC_SET_STRING(iovec[n++], unit);
+
+ free(c);
}
- if (unit)
- IOVEC_SET_STRING(iovec[n++], unit);
-
#ifdef HAVE_SELINUX
if (label) {
- selinux_context = malloc(sizeof("_SELINUX_CONTEXT=") + label_len);
- if (selinux_context) {
- *((char*) mempcpy(stpcpy(selinux_context, "_SELINUX_CONTEXT="), label, label_len)) = 0;
- IOVEC_SET_STRING(iovec[n++], selinux_context);
- }
+ selinux_context = alloca(sizeof("_SELINUX_CONTEXT=") + label_len);
+
+ *((char*) mempcpy(stpcpy(selinux_context, "_SELINUX_CONTEXT="), label, label_len)) = 0;
+ IOVEC_SET_STRING(iovec[n++], selinux_context);
} else {
security_context_t con;
if (getpidcon(ucred->pid, &con) >= 0) {
- selinux_context = strappend("_SELINUX_CONTEXT=", con);
- if (selinux_context)
- IOVEC_SET_STRING(iovec[n++], selinux_context);
+ selinux_context = strappenda("_SELINUX_CONTEXT=", con);
freecon(con);
+ IOVEC_SET_STRING(iovec[n++], selinux_context);
}
}
#endif
}
if (tv) {
- snprintf(source_time, sizeof(source_time) - 1, "_SOURCE_REALTIME_TIMESTAMP=%llu",
- (unsigned long long) timeval_load(tv));
- char_array_0(source_time);
+ sprintf(source_time, "_SOURCE_REALTIME_TIMESTAMP=%llu", (unsigned long long) timeval_load(tv));
IOVEC_SET_STRING(iovec[n++], source_time);
}
@@ -676,10 +653,9 @@ static void dispatch_message_real(
t = gethostname_malloc();
if (t) {
- hostname = strappend("_HOSTNAME=", t);
+ hostname = strappenda("_HOSTNAME=", t);
free(t);
- if (hostname)
- IOVEC_SET_STRING(iovec[n++], hostname);
+ IOVEC_SET_STRING(iovec[n++], hostname);
}
assert(n <= m);
diff --git a/src/login/logind-session.c b/src/login/logind-session.c
index 2f7ab3451f..662273b07f 100644
--- a/src/login/logind-session.c
+++ b/src/login/logind-session.c
@@ -465,7 +465,18 @@ static int session_create_cgroup(Session *s) {
assert(s->user->cgroup_path);
if (!s->cgroup_path) {
- if (asprintf(&p, "%s/%s", s->user->cgroup_path, s->id) < 0)
+ _cleanup_free_ char *name = NULL, *escaped = NULL;
+
+ name = strappend(s->id, ".session");
+ if (!name)
+ return log_oom();
+
+ escaped = cg_escape(name);
+ if (!escaped)
+ return log_oom();
+
+ p = strjoin(s->user->cgroup_path, "/", escaped, NULL);
+ if (!p)
return log_oom();
} else
p = s->cgroup_path;
diff --git a/src/login/logind-user.c b/src/login/logind-user.c
index 4b0ac5e737..9e2cbf646b 100644
--- a/src/login/logind-user.c
+++ b/src/login/logind-user.c
@@ -315,7 +315,17 @@ static int user_create_cgroup(User *u) {
assert(u);
if (!u->cgroup_path) {
- if (asprintf(&p, "%s/%s", u->manager->cgroup_path, u->name) < 0)
+ _cleanup_free_ char *name = NULL, *escaped = NULL;
+
+ if (asprintf(&name, "%lu.user", (unsigned long) u->uid) < 0)
+ return log_oom();
+
+ escaped = cg_escape(name);
+ if (!escaped)
+ return log_oom();
+
+ p = strjoin(u->manager->cgroup_path, "/", escaped, NULL);
+ if (!p)
return log_oom();
} else
p = u->cgroup_path;
diff --git a/src/login/sd-login.c b/src/login/sd-login.c
index 30e07a9322..157b7e0fb4 100644
--- a/src/login/sd-login.c
+++ b/src/login/sd-login.c
@@ -73,10 +73,6 @@ _public_ int sd_pid_get_machine_name(pid_t pid, char **name) {
}
_public_ int sd_pid_get_owner_uid(pid_t pid, uid_t *uid) {
- int r;
- _cleanup_free_ char *root = NULL, *cgroup = NULL, *cc = NULL;
- char *p;
- struct stat st;
if (pid < 0)
return -EINVAL;
@@ -84,36 +80,7 @@ _public_ int sd_pid_get_owner_uid(pid_t pid, uid_t *uid) {
if (!uid)
return -EINVAL;
- r = cg_pid_get_path_shifted(pid, &root, &cgroup);
- if (r < 0)
- return r;
-
- if (!startswith(cgroup, "/user/"))
- return -ENOENT;
-
- p = strchr(cgroup + 6, '/');
- if (!p)
- return -ENOENT;
-
- p++;
- p += strcspn(p, "/");
- *p = 0;
-
- r = cg_get_path(SYSTEMD_CGROUP_CONTROLLER, root, cgroup, &cc);
-
- if (r < 0)
- return -ENOMEM;
-
- r = lstat(cc, &st);
-
- if (r < 0)
- return -errno;
-
- if (!S_ISDIR(st.st_mode))
- return -ENOTDIR;
-
- *uid = st.st_uid;
- return 0;
+ return cg_pid_get_owner_uid(pid, uid);
}
_public_ int sd_uid_get_state(uid_t uid, char**state) {
diff --git a/src/nspawn/nspawn.c b/src/nspawn/nspawn.c
index 1e7df38c16..7b41571034 100644
--- a/src/nspawn/nspawn.c
+++ b/src/nspawn/nspawn.c
@@ -1212,7 +1212,7 @@ finish:
int main(int argc, char *argv[]) {
pid_t pid = 0;
int r = EXIT_FAILURE, k;
- _cleanup_free_ char *machine_root = NULL, *newcg = NULL;
+ _cleanup_free_ char *machine_root = NULL, *name = NULL, *escaped = NULL, *newcg = NULL;
_cleanup_close_ int master = -1;
int n_fd_passed;
const char *console = NULL;
@@ -1298,9 +1298,21 @@ int main(int argc, char *argv[]) {
goto finish;
}
- newcg = strjoin(machine_root, "/", arg_machine, ".nspawn", NULL);
+ name = strappend(arg_machine, ".nspawn");
+ if (!name) {
+ log_oom();
+ goto finish;
+ }
+
+ escaped = cg_escape(name);
+ if (!escaped) {
+ log_oom();
+ goto finish;
+ }
+
+ newcg = strjoin(machine_root, "/", escaped, NULL);
if (!newcg) {
- log_error("Failed to allocate cgroup path.");
+ log_oom();
goto finish;
}
diff --git a/src/shared/cgroup-util.c b/src/shared/cgroup-util.c
index e54b94658c..9ec4f40c88 100644
--- a/src/shared/cgroup-util.c
+++ b/src/shared/cgroup-util.c
@@ -1197,8 +1197,8 @@ int cg_pid_get_path_shifted(pid_t pid, char **root, char **cgroup) {
return 0;
}
-/* non-static only for testing purposes */
int cg_path_decode_unit(const char *cgroup, char **unit){
+ _cleanup_free_ char *unescaped = NULL;
char *p, *e, *c, *s, *k;
assert(cgroup);
@@ -1206,6 +1206,7 @@ int cg_path_decode_unit(const char *cgroup, char **unit){
e = strchrnul(cgroup, '/');
c = strndupa(cgroup, e - cgroup);
+ c = cg_unescape(c);
/* Could this be a valid unit name? */
if (!unit_name_is_valid(c, true))
@@ -1218,15 +1219,15 @@ int cg_path_decode_unit(const char *cgroup, char **unit){
return -EINVAL;
e += strspn(e, "/");
+
p = strchrnul(e, '/');
+ k = strndupa(e, p - e);
+ k = cg_unescape(k);
- /* Don't allow empty instance strings */
- if (p == e)
+ if (!unit_name_is_valid(k, false))
return -EINVAL;
- k = strndupa(e, p - e);
-
- s = unit_name_replace_instance(c, k);
+ s = strdup(k);
}
if (!s)
@@ -1320,7 +1321,7 @@ int cg_pid_get_user_unit(pid_t pid, char **unit) {
int cg_path_get_machine_name(const char *path, char **machine) {
const char *e, *n;
- char *s, *dot;
+ char *s, *r;
assert(path);
assert(machine);
@@ -1333,15 +1334,13 @@ int cg_path_get_machine_name(const char *path, char **machine) {
if (e == n)
return -ENOENT;
- s = strndup(e, n - e);
- if (!s)
- return -ENOMEM;
+ s = strndupa(e, n - e);
- dot = strrchr(s, '.');
- if (dot)
- *dot = 0;
+ r = strdup(cg_unescape(s));
+ if (!r)
+ return -ENOMEM;
- *machine = s;
+ *machine = r;
return 0;
}
@@ -1375,13 +1374,12 @@ int cg_path_get_session(const char *path, char **session) {
return -ENOENT;
n = strchrnul(e, '/');
- if (e == n)
+ if (n - e < 8)
return -ENOENT;
-
- if (n - e == 6 && memcmp(e, "shared", 6) == 0)
+ if (memcmp(n - 8, ".session", 8) != 0)
return -ENOENT;
- s = strndup(e, n - e);
+ s = strndup(e, n - e - 8);
if (!s)
return -ENOMEM;
@@ -1402,6 +1400,43 @@ int cg_pid_get_session(pid_t pid, char **session) {
return cg_path_get_session(cgroup, session);
}
+int cg_path_get_owner_uid(const char *path, uid_t *uid) {
+ const char *e, *n;
+ char *s;
+
+ assert(path);
+ assert(uid);
+
+ e = path_startswith(path, "/user/");
+ if (!e)
+ return -ENOENT;
+
+ n = strchrnul(e, '/');
+ if (n - e < 5)
+ return -ENOENT;
+ if (memcmp(n - 5, ".user", 5) != 0)
+ return -ENOENT;
+
+ s = strndupa(e, n - e - 5);
+ if (!s)
+ return -ENOMEM;
+
+ return parse_uid(s, uid);
+}
+
+int cg_pid_get_owner_uid(pid_t pid, uid_t *uid) {
+ _cleanup_free_ char *cgroup = NULL;
+ int r;
+
+ assert(uid);
+
+ r = cg_pid_get_path_shifted(pid, NULL, &cgroup);
+ if (r < 0)
+ return r;
+
+ return cg_path_get_owner_uid(cgroup, uid);
+}
+
int cg_controller_from_attr(const char *attr, char **controller) {
const char *dot;
char *c;
@@ -1430,3 +1465,55 @@ int cg_controller_from_attr(const char *attr, char **controller) {
*controller = c;
return 1;
}
+
+char *cg_escape(const char *p) {
+ bool need_prefix = false;
+
+ /* This implements very minimal escaping for names to be used
+ * as file names in the cgroup tree: any name which might
+ * conflict with a kernel name or is prefixed with '_' is
+ * prefixed with a '_'. That way, when reading cgroup names it
+ * is sufficient to remove a single prefixing underscore if
+ * there is one. */
+
+ /* The return value of this function (unlike cg_unescape())
+ * needs free()! */
+
+ if (p[0] == '_' || streq(p, "notify_on_release") || streq(p, "release_agent") || streq(p, "tasks"))
+ need_prefix = true;
+ else {
+ const char *dot;
+
+ dot = strrchr(p, '.');
+ if (dot) {
+
+ if (dot - p == 6 && memcmp(p, "cgroup", 6) == 0)
+ need_prefix = true;
+ else {
+ char *n;
+
+ n = strndupa(p, dot - p);
+
+ if (check_hierarchy(n) >= 0)
+ need_prefix = true;
+ }
+ }
+ }
+
+ if (need_prefix)
+ return strappend("_", p);
+ else
+ return strdup(p);
+}
+
+char *cg_unescape(const char *p) {
+ assert(p);
+
+ /* The return value of this function (unlike cg_escape())
+ * doesn't need free()! */
+
+ if (p[0] == '_')
+ return (char*) p+1;
+
+ return (char*) p;
+}
diff --git a/src/shared/cgroup-util.h b/src/shared/cgroup-util.h
index 5457d1bcaa..2099f934b4 100644
--- a/src/shared/cgroup-util.h
+++ b/src/shared/cgroup-util.h
@@ -75,6 +75,7 @@ int cg_get_user_path(char **path);
int cg_get_machine_path(char **path);
int cg_path_get_session(const char *path, char **session);
+int cg_path_get_owner_uid(const char *path, uid_t *uid);
int cg_path_get_unit(const char *path, char **unit);
int cg_path_get_user_unit(const char *path, char **unit);
int cg_path_get_machine_name(const char *path, char **machine);
@@ -82,6 +83,7 @@ int cg_path_get_machine_name(const char *path, char **machine);
int cg_pid_get_path_shifted(pid_t pid, char **root, char **cgroup);
int cg_pid_get_session(pid_t pid, char **session);
+int cg_pid_get_owner_uid(pid_t pid, uid_t *uid);
int cg_pid_get_unit(pid_t pid, char **unit);
int cg_pid_get_user_unit(pid_t pid, char **unit);
int cg_pid_get_machine_name(pid_t pid, char **machine);
@@ -91,3 +93,6 @@ int cg_path_decode_unit(const char *cgroup, char **unit);
char **cg_shorten_controllers(char **controllers);
int cg_controller_from_attr(const char *attr, char **controller);
+
+char *cg_escape(const char *p);
+char *cg_unescape(const char *p);
diff --git a/src/test/test-cgroup-util.c b/src/test/test-cgroup-util.c
index f632df11eb..95cede7a22 100644
--- a/src/test/test-cgroup-util.c
+++ b/src/test/test-cgroup-util.c
@@ -32,8 +32,8 @@ static void check_p_d_u(const char *path, int code, const char *result) {
}
static void test_path_decode_unit(void) {
- check_p_d_u("getty@.service/tty2", 0, "getty@tty2.service");
- check_p_d_u("getty@.service/tty2/xxx", 0, "getty@tty2.service");
+ check_p_d_u("getty@.service/getty@tty2.service", 0, "getty@tty2.service");
+ check_p_d_u("getty@.service/getty@tty2.service/xxx", 0, "getty@tty2.service");
check_p_d_u("getty@.service/", -EINVAL, NULL);
check_p_d_u("getty@.service", -EINVAL, NULL);
check_p_d_u("getty.service", 0, "getty.service");
@@ -56,9 +56,9 @@ static void check_p_g_u_u(const char *path, int code, const char *result) {
static void test_path_get_unit(void) {
check_p_g_u("/system/foobar.service/sdfdsaf", 0, "foobar.service");
- check_p_g_u("/system/getty@.service/tty5", 0, "getty@tty5.service");
- check_p_g_u("/system/getty@.service/tty5/aaa/bbb", 0, "getty@tty5.service");
- check_p_g_u("/system/getty@.service/tty5/", 0, "getty@tty5.service");
+ check_p_g_u("/system/getty@.service/getty@tty5.service", 0, "getty@tty5.service");
+ check_p_g_u("/system/getty@.service/getty@tty5.service/aaa/bbb", 0, "getty@tty5.service");
+ check_p_g_u("/system/getty@.service/getty@tty5.service/", 0, "getty@tty5.service");
check_p_g_u("/system/getty@tty6.service/tty5", 0, "getty@tty6.service");
check_p_g_u("sadfdsafsda", -ENOENT, NULL);
check_p_g_u("/system/getty####@tty6.service/tty5", -EINVAL, NULL);
@@ -70,7 +70,7 @@ static void test_path_get_user_unit(void) {
check_p_g_u_u("/user/lennart/2/systemd-21548/foobar.service/waldo/uuuux", 0, "foobar.service");
check_p_g_u_u("/user/lennart/2/systemd-21548/waldo/waldo/uuuux", -EINVAL, NULL);
check_p_g_u_u("/user/lennart/2/foobar.service", -ENOENT, NULL);
- check_p_g_u_u("/user/lennart/2/systemd-21548/foobar@.service/pie/pa/po", 0, "foobar@pie.service");
+ check_p_g_u_u("/user/lennart/2/systemd-21548/foobar@.service/foobar@pie.service/pa/po", 0, "foobar@pie.service");
}
static void test_get_paths(void) {
@@ -100,6 +100,7 @@ static void test_proc(void) {
FOREACH_DIRENT(de, d, break) {
_cleanup_free_ char *path = NULL, *path_shifted = NULL, *session = NULL, *unit = NULL, *user_unit = NULL, *machine = NULL, *prefix = NULL;
pid_t pid;
+ uid_t uid = (uid_t) -1;
if (de->d_type != DT_DIR &&
de->d_type != DT_UNKNOWN)
@@ -109,18 +110,23 @@ static void test_proc(void) {
if (r < 0)
continue;
+ if (is_kernel_thread(pid))
+ continue;
+
cg_pid_get_path(SYSTEMD_CGROUP_CONTROLLER, pid, &path);
cg_pid_get_path_shifted(pid, &prefix, &path_shifted);
+ cg_pid_get_owner_uid(pid, &uid);
cg_pid_get_session(pid, &session);
cg_pid_get_unit(pid, &unit);
cg_pid_get_user_unit(pid, &user_unit);
cg_pid_get_machine_name(pid, &machine);
- printf("%lu\t%s\t%s\t%s\t%s\t%s\t%s\t%s\n",
+ printf("%lu\t%s\t%s\t%s\t%lu\t%s\t%s\t%s\t%s\n",
(unsigned long) pid,
path,
prefix,
path_shifted,
+ (unsigned long) uid,
session,
unit,
user_unit,
@@ -128,12 +134,32 @@ static void test_proc(void) {
}
}
+static void test_escape_one(const char *s, const char *r) {
+ _cleanup_free_ char *b;
+
+ b = cg_escape(s);
+ assert_se(b);
+ assert_se(streq(b, r));
+
+ assert_se(streq(cg_unescape(b), s));
+}
+
+static void test_escape(void) {
+ test_escape_one("foobar", "foobar");
+ test_escape_one("foobar.service", "foobar.service");
+ test_escape_one("cgroup.service", "_cgroup.service");
+ test_escape_one("cpu.service", "_cpu.service");
+ test_escape_one("tasks", "_tasks");
+ test_escape_one("_foobar", "__foobar");
+}
+
int main(void) {
test_path_decode_unit();
test_path_get_unit();
test_path_get_user_unit();
test_get_paths();
test_proc();
+ test_escape();
return 0;
}