From 374ec6abf31ada6ca554cc8ea99b282373fac010 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Tue, 2 Jul 2013 02:32:24 +0200 Subject: [PATCH] libsystemd-logind: fix detection of session/user/machine of a PID --- TODO | 2 +- src/login/logind-machine.c | 2 +- src/login/logind-session.c | 2 +- src/shared/cgroup-util.c | 102 +++++++++++++++--------------------- src/test/test-cgroup-util.c | 32 +++++------ 5 files changed, 61 insertions(+), 79 deletions(-) diff --git a/TODO b/TODO index cde2ced31..96ed2c06d 100644 --- a/TODO +++ b/TODO @@ -28,7 +28,7 @@ Fedora 19: Features: -* libsystemd-logind: recognize new session/user/machine units +* fix killing spree logic in systemd-user-sessions * logind: implement session kill exceptions diff --git a/src/login/logind-machine.c b/src/login/logind-machine.c index e4edd40db..a1342c155 100644 --- a/src/login/logind-machine.c +++ b/src/login/logind-machine.c @@ -235,7 +235,7 @@ static int machine_start_scope(Machine *m) { if (!escaped) return log_oom(); - m->scope = strjoin("machine.", m->name, ".scope", NULL); + m->scope = strjoin("machine-", m->name, ".scope", NULL); if (!m->scope) return log_oom(); diff --git a/src/login/logind-session.c b/src/login/logind-session.c index 93e403723..6e1bf6d56 100644 --- a/src/login/logind-session.c +++ b/src/login/logind-session.c @@ -467,7 +467,7 @@ static int session_start_scope(Session *s) { dbus_error_init(&error); if (!s->scope) { - s->scope = strjoin("session.", s->id, ".scope", NULL); + s->scope = strjoin("session-", s->id, ".scope", NULL); if (!s->scope) return log_oom(); diff --git a/src/shared/cgroup-util.c b/src/shared/cgroup-util.c index 0e5da23ec..390259e3e 100644 --- a/src/shared/cgroup-util.c +++ b/src/shared/cgroup-util.c @@ -1178,23 +1178,6 @@ int cg_pid_get_unit(pid_t pid, char **unit) { return cg_path_get_unit(cgroup, unit); } -static const char *skip_user(const char *p) { - size_t n; - - assert(p); - - p += strspn(p, "/"); - - n = strcspn(p, "/"); - if (n <= 5 || memcmp(p + n - 5, ".user", 5) != 0) - return p; - - p += n; - p += strspn(p, "/"); - - return p; -} - static const char *skip_session(const char *p) { size_t n; @@ -1203,7 +1186,7 @@ static const char *skip_session(const char *p) { p += strspn(p, "/"); n = strcspn(p, "/"); - if (n <= 8 || memcmp(p + n - 8, ".session", 8) != 0) + if (n <= 12 || memcmp(p, "session-", 8) != 0 || memcmp(p + n - 6, ".scope", 6) != 0) return NULL; p += n; @@ -1212,23 +1195,6 @@ static const char *skip_session(const char *p) { return p; } -static const char *skip_systemd_label(const char *p) { - size_t n; - - assert(p); - - p += strspn(p, "/"); - - n = strcspn(p, "/"); - if (n < 8 || memcmp(p, "systemd-", 8) != 0) - return p; - - p += n; - p += strspn(p, "/"); - - return p; -} - int cg_path_get_user_unit(const char *path, char **unit) { const char *e; @@ -1242,16 +1208,13 @@ int cg_path_get_user_unit(const char *path, char **unit) { /* Skip slices, if there are any */ e = skip_slices(path); - /* Skip the user name, if there is one */ - e = skip_user(e); - - /* Skip the session ID, require that there is one */ + /* Skip the session scope, require that there is one */ e = skip_session(e); if (!e) return -ENOENT; - /* Skip the systemd cgroup, if there is one */ - e = skip_systemd_label(e); + /* And skip more slices */ + e = skip_slices(e); return cg_path_decode_unit(e, unit); } @@ -1272,6 +1235,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, *x; char *s, *r; + size_t l; assert(path); assert(machine); @@ -1286,11 +1250,17 @@ int cg_path_get_machine_name(const char *path, char **machine) { s = strndupa(e, n - e); s = cg_unescape(s); - x = endswith(s, ".machine"); + x = startswith(s, "machine-"); if (!x) return -ENOENT; + if (!endswith(x, ".scope")) + return -ENOENT; + + l = strlen(x); + if (l <= 6) + return -ENOENT; - r = strndup(s, x - s); + r = strndup(x, l - 6); if (!r) return -ENOMEM; @@ -1312,8 +1282,9 @@ 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; - char *s; + const char *e, *n, *x; + char *s, *r; + size_t l; assert(path); assert(session); @@ -1321,20 +1292,28 @@ int cg_path_get_session(const char *path, char **session) { /* Skip slices, if there are any */ e = skip_slices(path); - /* Skip the user name, if there is one */ - e = skip_user(e); - n = strchrnul(e, '/'); - if (n - e < 8) + if (e == n) return -ENOENT; - if (memcmp(n - 8, ".session", 8) != 0) + + s = strndupa(e, n - e); + s = cg_unescape(s); + + x = startswith(s, "session-"); + if (!x) + return -ENOENT; + if (!endswith(x, ".scope")) return -ENOENT; - s = strndup(e, n - e - 8); - if (!s) + l = strlen(x); + if (l <= 6) + return -ENOENT; + + r = strndup(x, l - 6); + if (!r) return -ENOMEM; - *session = s; + *session = r; return 0; } @@ -1352,22 +1331,25 @@ int cg_pid_get_session(pid_t pid, char **session) { } int cg_path_get_owner_uid(const char *path, uid_t *uid) { - const char *e, *n; + _cleanup_free_ char *slice = NULL; + const char *e; char *s; + int r; assert(path); assert(uid); - /* Skip slices, if there are any */ - e = skip_slices(path); + r = cg_path_get_slice(path, &slice); + if (r < 0) + return r; - n = strchrnul(e, '/'); - if (n - e < 5) + e = startswith(slice, "user-"); + if (!e) return -ENOENT; - if (memcmp(n - 5, ".user", 5) != 0) + if (!endswith(slice, ".slice")) return -ENOENT; - s = strndupa(e, n - e - 5); + s = strndupa(e, strlen(e) - 6); if (!s) return -ENOMEM; diff --git a/src/test/test-cgroup-util.c b/src/test/test-cgroup-util.c index f6317e5d3..ed2c6aeea 100644 --- a/src/test/test-cgroup-util.c +++ b/src/test/test-cgroup-util.c @@ -66,14 +66,14 @@ static void check_p_g_u_u(const char *path, int code, const char *result) { } static void test_path_get_user_unit(void) { - check_p_g_u_u("/user.slice/1000.user/2.session/systemd-21548/foobar.service", 0, "foobar.service"); - check_p_g_u_u("/user.slice/1002.user/2.session/systemd-21548/foobar.service/waldo", 0, "foobar.service"); - check_p_g_u_u("/user.slice/1000.user/2.session/systemd-21548/foobar.service/waldo/uuuux", 0, "foobar.service"); - check_p_g_u_u("/user.slice/1000.user/2.session/systemd-21548/waldo/waldo/uuuux", -EINVAL, NULL); - check_p_g_u_u("/user.slice/1000.user/2.session/foobar.service", 0, "foobar.service"); - check_p_g_u_u("/user.slice/1000.user/2.session/systemd-21548/foobar@.service/foobar@pie.service/pa/po", 0, "foobar@pie.service"); - check_p_g_u_u("/2.session/systemd-21548/foobar@.service/foobar@pie.service/pa/po", 0, "foobar@pie.service"); - check_p_g_u_u("/xyz.slice/xyz-waldo.slice/77.session/systemd-21548/foobar@.service/foobar@pie.service/pa/po", 0, "foobar@pie.service"); + check_p_g_u_u("/user.slice/user-1000.slice/session-2.scope/foobar.service", 0, "foobar.service"); + check_p_g_u_u("/user.slice/user-1000.slice/session-2.scope/waldo.slice/foobar.service", 0, "foobar.service"); + check_p_g_u_u("/user.slice/user-1002.slice/session-2.scope/foobar.service/waldo", 0, "foobar.service"); + check_p_g_u_u("/user.slice/user-1000.slice/session-2.scope/foobar.service/waldo/uuuux", 0, "foobar.service"); + check_p_g_u_u("/user.slice/user-1000.slice/session-2.scope/waldo/waldo/uuuux", -EINVAL, NULL); + check_p_g_u_u("/user.slice/user-1000.slice/session-2.scope/foobar@.service/foobar@pie.service/pa/po", 0, "foobar@pie.service"); + check_p_g_u_u("/session-2.scope/foobar@.service/foobar@pie.service/pa/po", 0, "foobar@pie.service"); + check_p_g_u_u("/xyz.slice/xyz-waldo.slice/session-77.scope/foobar@.service/foobar@pie.service/pa/po", 0, "foobar@pie.service"); check_p_g_u_u("/meh.service", -ENOENT, NULL); } @@ -85,8 +85,8 @@ static void check_p_g_s(const char *path, int code, const char *result) { } static void test_path_get_session(void) { - check_p_g_s("/user.slice/1000.user/2.session/systemd-21548/foobar.service", 0, "2"); - check_p_g_s("/3.session", 0, "3"); + check_p_g_s("/user.slice/user-1000.slice/session-2.scope/foobar.service", 0, "2"); + check_p_g_s("/session-3.scope", 0, "3"); check_p_g_s("", -ENOENT, 0); } @@ -98,8 +98,8 @@ static void check_p_g_o_u(const char *path, int code, uid_t result) { } static void test_path_get_owner_uid(void) { - check_p_g_o_u("/user.slice/1000.user/2.session/systemd-21548/foobar.service", 0, 1000); - check_p_g_o_u("/1006.user", 0, 1006); + check_p_g_o_u("/user.slice/user-1000.slice/session-2.scope/foobar.service", 0, 1000); + check_p_g_o_u("/user.slice/user-1006.slice", 0, 1006); check_p_g_o_u("", -ENOENT, 0); } @@ -111,10 +111,10 @@ static void check_p_g_m_n(const char *path, int code, const char *result) { } static void test_path_get_machine_name(void) { - check_p_g_m_n("/user.slice/foobar.machine", 0, "foobar"); - check_p_g_m_n("/foobar.machine", 0, "foobar"); - check_p_g_m_n("/user.slice/user-kuux.slice/foobar.machine", 0, "foobar"); - check_p_g_m_n("/user.slice/user-kuux.slice/foobar.machine/asjhdkj", 0, "foobar"); + check_p_g_m_n("/user.slice/machine-foobar.scope", 0, "foobar"); + check_p_g_m_n("/machine-foobar.scope", 0, "foobar"); + check_p_g_m_n("/user.slice/user-kuux.slice/machine-foobar.scope", 0, "foobar"); + check_p_g_m_n("/user.slice/user-kuux.slice/machine-foobar.scope/asjhdkj", 0, "foobar"); check_p_g_m_n("", -ENOENT, NULL); } -- 2.30.2