From d3cfab3148de482649e22d9dbbfec6e967a80856 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Thu, 18 May 2017 20:58:23 -0400 Subject: [PATCH 1/7] sd-login: read list of uids of sessions from UIDS not ACTIVE_SESSIONS As described by Luke Shumaker: sd_seat_get_sessions looks at /run/systemd/seats/${seat_name}:SESSIONS to get the list of sessions (which I believe is correct), and at /run/systemd/seats/${seat_name}:ACTIVE_SESSIONS for the list of users (which I believe is incorrect); I believe that it should look at the UIDS field for the list of users. As far as I can tell, the ACTIVE_SESSIONS field is never even present in the seats file. I also believe that this has been broken since the function was first committed almost 6 years ago. Fixes #5743. --- src/libsystemd/sd-login/sd-login.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libsystemd/sd-login/sd-login.c b/src/libsystemd/sd-login/sd-login.c index d2cfbdf5b0..cdbdc37856 100644 --- a/src/libsystemd/sd-login/sd-login.c +++ b/src/libsystemd/sd-login/sd-login.c @@ -687,7 +687,7 @@ _public_ int sd_seat_get_sessions(const char *seat, char ***sessions, uid_t **ui r = parse_env_file(p, NEWLINE, "SESSIONS", &s, - "ACTIVE_SESSIONS", &t, + "UIDS", &t, NULL); if (r == -ENOENT) return -ENXIO; From cc6182e8540a348c664bcbb4af85701ddc36e5a6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Thu, 18 May 2017 20:48:09 -0400 Subject: [PATCH 2/7] sd-login: always return two arrays of same length from sd_seat_get_sessions sd_seat_get_sessions returns two arrays, that in principle should always match: the session names and corresponding uids. The second array could be shorter only if parsing or uid conversion fails. But in that case there is no way to tell *which* uid is wrong, so they are *all* useless. It's better to simplify things and just return an error if parsing fails. --- man/sd_seat_get_active.xml | 5 +++-- src/libsystemd/sd-login/sd-login.c | 2 +- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/man/sd_seat_get_active.xml b/man/sd_seat_get_active.xml index c5e6ddab02..3dd461f83f 100644 --- a/man/sd_seat_get_active.xml +++ b/man/sd_seat_get_active.xml @@ -105,8 +105,9 @@ one (NULL terminated) with the session identifiers of the sessions and one with the user identifiers of the Unix users the sessions belong to. An additional parameter may - be used to return the number of entries in the latter array. The - two arrays and the latter parameter may be passed as + be used to return the number of entries in the latter array. This + value is the same the return value, if the latter is nonnegative. + The two arrays and the last parameter may be passed as NULL in case these values need not to be determined. The arrays and the strings referenced by them need to be freed with the libc diff --git a/src/libsystemd/sd-login/sd-login.c b/src/libsystemd/sd-login/sd-login.c index cdbdc37856..ed15efa104 100644 --- a/src/libsystemd/sd-login/sd-login.c +++ b/src/libsystemd/sd-login/sd-login.c @@ -723,7 +723,7 @@ _public_ int sd_seat_get_sessions(const char *seat, char ***sessions, uid_t **ui r = parse_uid(k, b + i); if (r < 0) - continue; + return r; i++; } From 19d64d10c049e5cffefff97e4c01fa3b69c2059b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Thu, 18 May 2017 21:55:44 -0400 Subject: [PATCH 3/7] sd-login: fix return value of sd_pid_get_session We'd return -ENXIO, even thoug -ENODATA is documented. --- src/libsystemd/sd-login/sd-login.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/libsystemd/sd-login/sd-login.c b/src/libsystemd/sd-login/sd-login.c index ed15efa104..030131eeda 100644 --- a/src/libsystemd/sd-login/sd-login.c +++ b/src/libsystemd/sd-login/sd-login.c @@ -56,11 +56,13 @@ */ _public_ int sd_pid_get_session(pid_t pid, char **session) { + int r; assert_return(pid >= 0, -EINVAL); assert_return(session, -EINVAL); - return cg_pid_get_session(pid, session); + r = cg_pid_get_session(pid, session); + return r == -ENXIO ? -ENODATA : r; } _public_ int sd_pid_get_unit(pid_t pid, char **unit) { From d440fb97ba36e0a1dcf03e41601e53303a4d6288 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Thu, 18 May 2017 22:11:08 -0400 Subject: [PATCH 4/7] sd-login: fix return value of sd_pid_get_user_unit E.g. "/user.slice/user-1000.slice/session-15.scope" would cause -ENXIO to be returned. --- src/libsystemd/sd-login/sd-login.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/libsystemd/sd-login/sd-login.c b/src/libsystemd/sd-login/sd-login.c index 030131eeda..cd844b3105 100644 --- a/src/libsystemd/sd-login/sd-login.c +++ b/src/libsystemd/sd-login/sd-login.c @@ -74,11 +74,13 @@ _public_ int sd_pid_get_unit(pid_t pid, char **unit) { } _public_ int sd_pid_get_user_unit(pid_t pid, char **unit) { + int r; assert_return(pid >= 0, -EINVAL); assert_return(unit, -EINVAL); - return cg_pid_get_user_unit(pid, unit); + r = cg_pid_get_user_unit(pid, unit); + return r == -ENXIO ? -ENODATA : r; } _public_ int sd_pid_get_machine_name(pid_t pid, char **name) { From ce737f46cd8aa8bfa0b586d0a821c815835000ab Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Fri, 12 May 2017 14:25:17 -0400 Subject: [PATCH 5/7] test-login: make the test non-manual test-login.c is largely rewritten to use _cleanup_ and give more meaningful messages (function names are used instead of creative terms like "active session", so that when something unexpected is returned, it's much easier to see what function is responsible). The monitoring part is only activated if '-m' is passed on the command line. It runs against the information from /run/systemd/ in the live system, but that should be OK: logind/sd-login interface is supposed to be stable and both backwards and forwards compatible. If not running in a login session, some tests are skipped. Those two changes together mean that it's possible to run test-login in the test suite. Tests for sd_pid_get_{unit,user_unit,slice} are added. --- Makefile.am | 2 +- man/sd_pid_get_session.xml | 8 +- man/sd_session_is_active.xml | 5 +- src/libsystemd/sd-login/test-login.c | 318 +++++++++++++++------------ src/test/meson.build | 3 +- 5 files changed, 186 insertions(+), 150 deletions(-) diff --git a/Makefile.am b/Makefile.am index 771efa4f8e..cd9a683e57 100644 --- a/Makefile.am +++ b/Makefile.am @@ -6096,10 +6096,10 @@ test_login_tables_LDADD = \ liblogind-core.la manual_tests += \ - test-login \ test-inhibit tests += \ + test-login \ test-login-tables \ test-login-shared diff --git a/man/sd_pid_get_session.xml b/man/sd_pid_get_session.xml index 806cff34e4..0c135ba871 100644 --- a/man/sd_pid_get_session.xml +++ b/man/sd_pid_get_session.xml @@ -177,7 +177,7 @@ processes, user processes that are shared between multiple sessions of the same user, or kernel threads). For processes not being part of a login session, this function will fail with - -ENODATA. The returned string needs to be freed with the libc + -ENODATA. The returned string needs to be freed with the libc free3 call after use. @@ -189,7 +189,7 @@ paths. Note that not all processes are part of a system unit/service (e.g. user processes, or kernel threads). For processes not being part of a systemd system unit, this function - will fail with -ENODATA. (More specifically, this call will not + will fail with -ENODATA. (More specifically, this call will not work for kernel threads.) The returned string needs to be freed with the libc free3 @@ -208,7 +208,7 @@ multiple login sessions of the same user, whereas sd_pid_get_session() will fail. For processes not being part of a login session and not being a shared process - of a user, this function will fail with -ENODATA. + of a user, this function will fail with -ENODATA. sd_pid_get_machine_name() may be used to determine the name of the VM or container is a member of. The @@ -217,7 +217,7 @@ free3 call after use. For processes not part of a VM or containers, this - function fails with -ENODATA. + function fails with -ENODATA. sd_pid_get_slice() may be used to determine the slice unit the process is a member of. See diff --git a/man/sd_session_is_active.xml b/man/sd_session_is_active.xml index a6076b177a..f95e74ead6 100644 --- a/man/sd_session_is_active.xml +++ b/man/sd_session_is_active.xml @@ -184,8 +184,9 @@ sd_session_get_seat() may be used to determine the seat identifier of the seat the session identified by the specified session identifier belongs to. Note that not all - sessions are attached to a seat, this call will fail for them. The - returned string needs to be freed with the libc + sessions are attached to a seat, this call will fail (returning + -ENODATA) for them. The returned string needs + to be freed with the libc free3 call after use. diff --git a/src/libsystemd/sd-login/test-login.c b/src/libsystemd/sd-login/test-login.c index 9de33d85db..fb7d4e2ece 100644 --- a/src/libsystemd/sd-login/test-login.c +++ b/src/libsystemd/sd-login/test-login.c @@ -25,173 +25,197 @@ #include "alloc-util.h" #include "fd-util.h" #include "format-util.h" +#include "log.h" #include "string-util.h" #include "strv.h" #include "util.h" +static char* format_uids(char **buf, uid_t* uids, int count) { + int pos = 0, k, inc; + size_t size = (DECIMAL_STR_MAX(uid_t) + 1) * count + 1; + + assert_se(*buf = malloc(size)); + + for (k = 0; k < count; k++) { + sprintf(*buf + pos, "%s"UID_FMT"%n", k > 0 ? " " : "", uids[k], &inc); + pos += inc; + } + + assert_se(pos < size); + (*buf)[pos] = '\0'; + + return *buf; +} + static void test_login(void) { _cleanup_close_pair_ int pair[2] = { -1, -1 }; - _cleanup_free_ char *pp = NULL, *qq = NULL; + _cleanup_free_ char *pp = NULL, *qq = NULL, + *display_session = NULL, *cgroup = NULL, + *display = NULL, *remote_user = NULL, *remote_host = NULL, + *type = NULL, *class = NULL, *state = NULL, *state2 = NULL, + *seat = NULL, *session = NULL, + *unit = NULL, *user_unit = NULL, *slice = NULL; int r, k; uid_t u, u2; - char *seat, *type, *class, *display, *remote_user, *remote_host, *display_session, *cgroup; - char *session; - char *state; - char *session2; - char *t; - char **seats, **sessions, **machines; - uid_t *uids; - unsigned n; - struct pollfd pollfd; - sd_login_monitor *m = NULL; + char *t, **seats, **sessions; - assert_se(sd_pid_get_session(0, &session) == 0); - printf("session = %s\n", session); + assert_se(sd_pid_get_unit(0, &unit) >= 0); + log_info("sd_pid_get_unit(0, …) → \"%s\"", unit); - assert_se(sd_pid_get_owner_uid(0, &u2) == 0); - printf("user = "UID_FMT"\n", u2); - - assert_se(sd_pid_get_cgroup(0, &cgroup) == 0); - printf("cgroup = %s\n", cgroup); - free(cgroup); - - display_session = NULL; - r = sd_uid_get_display(u2, &display_session); + r = sd_pid_get_user_unit(0, &user_unit); assert_se(r >= 0 || r == -ENODATA); - printf("user's display session = %s\n", strna(display_session)); - free(display_session); + log_info("sd_pid_get_user_unit(0, …) → \"%s\"", user_unit); - assert_se(socketpair(AF_UNIX, SOCK_STREAM, 0, pair) == 0); - sd_peer_get_session(pair[0], &pp); - sd_peer_get_session(pair[1], &qq); - assert_se(streq_ptr(pp, qq)); + assert_se(sd_pid_get_slice(0, &slice) >= 0); + log_info("sd_pid_get_slice(0, …) → \"%s\"", slice); - r = sd_uid_get_sessions(u2, false, &sessions); - assert_se(r >= 0); - assert_se(r == (int) strv_length(sessions)); - assert_se(t = strv_join(sessions, ", ")); - strv_free(sessions); - printf("sessions = %s\n", t); - free(t); + r = sd_pid_get_session(0, &session); + if (r < 0) { + log_warning_errno(r, "sd_pid_get_session(0, …): %m"); + if (r == -ENODATA) + log_info("Seems we are not running in a session, skipping some tests."); + } else { + log_info("sd_pid_get_session(0, …) → \"%s\"", session); - assert_se(r == sd_uid_get_sessions(u2, false, NULL)); + assert_se(sd_pid_get_owner_uid(0, &u2) == 0); + log_info("sd_pid_get_owner_uid(0, …) → "UID_FMT, u2); - r = sd_uid_get_seats(u2, false, &seats); - assert_se(r >= 0); - assert_se(r == (int) strv_length(seats)); - assert_se(t = strv_join(seats, ", ")); - strv_free(seats); - printf("seats = %s\n", t); - free(t); + assert_se(sd_pid_get_cgroup(0, &cgroup) == 0); + log_info("sd_pid_get_cgroup(0, …) → \"%s\"", cgroup); - assert_se(r == sd_uid_get_seats(u2, false, NULL)); + r = sd_uid_get_display(u2, &display_session); + assert_se(r >= 0 || r == -ENODATA); + log_info("sd_uid_get_display("UID_FMT", …) → \"%s\"", + u2, strnull(display_session)); - r = sd_session_is_active(session); - assert_se(r >= 0); - printf("active = %s\n", yes_no(r)); + assert_se(socketpair(AF_UNIX, SOCK_STREAM, 0, pair) == 0); + sd_peer_get_session(pair[0], &pp); + sd_peer_get_session(pair[1], &qq); + assert_se(streq_ptr(pp, qq)); - r = sd_session_is_remote(session); - assert_se(r >= 0); - printf("remote = %s\n", yes_no(r)); + r = sd_uid_get_sessions(u2, false, &sessions); + assert_se(r >= 0); + assert_se(r == (int) strv_length(sessions)); + assert_se(t = strv_join(sessions, " ")); + strv_free(sessions); + log_info("sd_uid_get_sessions("UID_FMT", …) → [%i] \"%s\"", u2, r, t); + free(t); - r = sd_session_get_state(session, &state); - assert_se(r >= 0); - printf("state = %s\n", state); - free(state); + assert_se(r == sd_uid_get_sessions(u2, false, NULL)); - assert_se(sd_session_get_uid(session, &u) >= 0); - printf("uid = "UID_FMT"\n", u); - assert_se(u == u2); + r = sd_uid_get_seats(u2, false, &seats); + assert_se(r >= 0); + assert_se(r == (int) strv_length(seats)); + assert_se(t = strv_join(seats, " ")); + strv_free(seats); + log_info("sd_uid_get_seats("UID_FMT", …) → [%i] \"%s\"", u2, r, t); + free(t); - assert_se(sd_session_get_type(session, &type) >= 0); - printf("type = %s\n", type); - free(type); + assert_se(r == sd_uid_get_seats(u2, false, NULL)); + } - assert_se(sd_session_get_class(session, &class) >= 0); - printf("class = %s\n", class); - free(class); + if (session) { + r = sd_session_is_active(session); + assert_se(r >= 0); + log_info("sd_session_is_active(\"%s\") → %s", session, yes_no(r)); - display = NULL; - r = sd_session_get_display(session, &display); - assert_se(r >= 0 || r == -ENODATA); - printf("display = %s\n", strna(display)); - free(display); + r = sd_session_is_remote(session); + assert_se(r >= 0); + log_info("sd_session_is_remote(\"%s\") → %s", session, yes_no(r)); - remote_user = NULL; - r = sd_session_get_remote_user(session, &remote_user); - assert_se(r >= 0 || r == -ENODATA); - printf("remote_user = %s\n", strna(remote_user)); - free(remote_user); + r = sd_session_get_state(session, &state); + assert_se(r >= 0); + log_info("sd_session_get_state(\"%s\") → \"%s\"", session, state); - remote_host = NULL; - r = sd_session_get_remote_host(session, &remote_host); - assert_se(r >= 0 || r == -ENODATA); - printf("remote_host = %s\n", strna(remote_host)); - free(remote_host); + assert_se(sd_session_get_uid(session, &u) >= 0); + log_info("sd_session_get_uid(\"%s\") → "UID_FMT, session, u); + assert_se(u == u2); - assert_se(sd_session_get_seat(session, &seat) >= 0); - printf("seat = %s\n", seat); + assert_se(sd_session_get_type(session, &type) >= 0); + log_info("sd_session_get_type(\"%s\") → \"%s\"", session, type); - r = sd_seat_can_multi_session(seat); - assert_se(r >= 0); - printf("can do multi session = %s\n", yes_no(r)); + assert_se(sd_session_get_class(session, &class) >= 0); + log_info("sd_session_get_class(\"%s\") → \"%s\"", session, class); - r = sd_seat_can_tty(seat); - assert_se(r >= 0); - printf("can do tty = %s\n", yes_no(r)); + r = sd_session_get_display(session, &display); + assert_se(r >= 0 || r == -ENODATA); + log_info("sd_session_get_display(\"%s\") → \"%s\"", session, strna(display)); - r = sd_seat_can_graphical(seat); - assert_se(r >= 0); - printf("can do graphical = %s\n", yes_no(r)); + r = sd_session_get_remote_user(session, &remote_user); + assert_se(r >= 0 || r == -ENODATA); + log_info("sd_session_get_remote_user(\"%s\") → \"%s\"", + session, strna(remote_user)); - assert_se(sd_uid_get_state(u, &state) >= 0); - printf("state = %s\n", state); + r = sd_session_get_remote_host(session, &remote_host); + assert_se(r >= 0 || r == -ENODATA); + log_info("sd_session_get_remote_host(\"%s\") → \"%s\"", + session, strna(remote_host)); - assert_se(sd_uid_is_on_seat(u, 0, seat) > 0); + r = sd_session_get_seat(session, &seat); + if (r >= 0) { + assert_se(seat); - k = sd_uid_is_on_seat(u, 1, seat); - assert_se(k >= 0); - assert_se(!!r == !!r); + log_info("sd_session_get_display(\"%s\") → \"%s\"", session, seat); - assert_se(sd_seat_get_active(seat, &session2, &u2) >= 0); - printf("session2 = %s\n", session2); - printf("uid2 = "UID_FMT"\n", u2); + r = sd_seat_can_multi_session(seat); + assert_se(r >= 0); + log_info("sd_session_can_multi_seat(\"%s\") → %s", seat, yes_no(r)); - r = sd_seat_get_sessions(seat, &sessions, &uids, &n); - assert_se(r >= 0); - printf("n_sessions = %i\n", r); - assert_se(r == (int) strv_length(sessions)); - assert_se(t = strv_join(sessions, ", ")); - strv_free(sessions); - printf("sessions = %s\n", t); - free(t); - printf("uids ="); - for (k = 0; k < (int) n; k++) - printf(" "UID_FMT, uids[k]); - printf("\n"); - free(uids); + r = sd_seat_can_tty(seat); + assert_se(r >= 0); + log_info("sd_session_can_tty(\"%s\") → %s", seat, yes_no(r)); - assert_se(sd_seat_get_sessions(seat, NULL, NULL, NULL) == r); + r = sd_seat_can_graphical(seat); + assert_se(r >= 0); + log_info("sd_session_can_graphical(\"%s\") → %s", seat, yes_no(r)); + } else { + log_info_errno(r, "sd_session_get_display(\"%s\"): %m", session); + assert_se(r == -ENODATA); + } - free(session); - free(state); - free(session2); - free(seat); + assert_se(sd_uid_get_state(u, &state2) >= 0); + log_info("sd_uid_get_state("UID_FMT", …) → %s", u, state2); + } + + if (seat) { + _cleanup_free_ char *session2 = NULL, *buf = NULL; + _cleanup_free_ uid_t *uids = NULL; + unsigned n; + + assert_se(sd_uid_is_on_seat(u, 0, seat) > 0); + + k = sd_uid_is_on_seat(u, 1, seat); + assert_se(k >= 0); + assert_se(!!k == !!r); + + assert_se(sd_seat_get_active(seat, &session2, &u2) >= 0); + log_info("sd_seat_get_active(\"%s\", …) → \"%s\", "UID_FMT, seat, session2, u2); + + r = sd_seat_get_sessions(seat, &sessions, &uids, &n); + assert_se(r >= 0); + assert_se(r == (int) strv_length(sessions)); + assert_se(t = strv_join(sessions, " ")); + strv_free(sessions); + log_info("sd_seat_get_sessions(\"%s\", …) → %i, \"%s\", [%i] {%s}", + seat, r, t, n, format_uids(&buf, uids, n)); + free(t); + + assert_se(sd_seat_get_sessions(seat, NULL, NULL, NULL) == r); + } r = sd_get_seats(&seats); assert_se(r >= 0); assert_se(r == (int) strv_length(seats)); assert_se(t = strv_join(seats, ", ")); strv_free(seats); - printf("n_seats = %i\n", r); - printf("seats = %s\n", t); - free(t); + log_info("sd_get_seats(…) → [%i] \"%s\"", r, t); + t = mfree(t); assert_se(sd_get_seats(NULL) == r); r = sd_seat_get_active(NULL, &t, NULL); - assert_se(r >= 0); - printf("active session on current seat = %s\n", t); + assert_se(IN_SET(r, 0, -ENODATA)); + log_info("sd_seat_get_active(NULL, …) (active session on current seat) → %s", strnull(t)); free(t); r = sd_get_sessions(&sessions); @@ -199,40 +223,47 @@ static void test_login(void) { assert_se(r == (int) strv_length(sessions)); assert_se(t = strv_join(sessions, ", ")); strv_free(sessions); - printf("n_sessions = %i\n", r); - printf("sessions = %s\n", t); + log_info("sd_get_sessions(…) → [%i] \"%s\"", r, t); free(t); assert_se(sd_get_sessions(NULL) == r); - r = sd_get_uids(&uids); - assert_se(r >= 0); + { + _cleanup_free_ uid_t *uids = NULL; + _cleanup_free_ char *buf = NULL; - printf("uids ="); - for (k = 0; k < r; k++) - printf(" "UID_FMT, uids[k]); - printf("\n"); - free(uids); + r = sd_get_uids(&uids); + assert_se(r >= 0); + log_info("sd_get_uids(…) → [%i] {%s}", r, format_uids(&buf, uids, r)); - printf("n_uids = %i\n", r); - assert_se(sd_get_uids(NULL) == r); + assert_se(sd_get_uids(NULL) == r); + } - r = sd_get_machine_names(&machines); - assert_se(r >= 0); - assert_se(r == (int) strv_length(machines)); - assert_se(t = strv_join(machines, ", ")); - strv_free(machines); - printf("n_machines = %i\n", r); - printf("machines = %s\n", t); - free(t); + { + _cleanup_strv_free_ char **machines = NULL; + _cleanup_free_ char *buf = NULL; + + r = sd_get_machine_names(&machines); + assert_se(r >= 0); + assert_se(r == (int) strv_length(machines)); + assert_se(buf = strv_join(machines, " ")); + + log_info("sd_get_machines(…) → [%i] \"%s\"", r, buf); + } +} + +static void test_monitor(void) { + sd_login_monitor *m = NULL; + unsigned n; + int r; r = sd_login_monitor_new("session", &m); assert_se(r >= 0); for (n = 0; n < 5; n++) { + struct pollfd pollfd = {}; usec_t timeout, nw; - zero(pollfd); assert_se((pollfd.fd = sd_login_monitor_get_fd(m)) >= 0); assert_se((pollfd.events = sd_login_monitor_get_events(m)) >= 0); @@ -258,7 +289,12 @@ int main(int argc, char* argv[]) { log_parse_environment(); log_open(); + log_info("/* Information printed is from the live system */"); + test_login(); + if (streq_ptr(argv[1], "-m")) + test_monitor(); + return 0; } diff --git a/src/test/meson.build b/src/test/meson.build index 4ae1210fe1..6573bed00f 100644 --- a/src/test/meson.build +++ b/src/test/meson.build @@ -786,8 +786,7 @@ tests += [ [['src/libsystemd/sd-login/test-login.c'], [], - [], - '', 'manual'], + []], ] ############################################################ From 171f8f591ff27ebb5ff475b7a9d1f13a846c9331 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Thu, 18 May 2017 22:32:19 -0400 Subject: [PATCH 6/7] sd-login,test-login: return -ENODATA from sd_pid_get_unit too After all, we might be running on a non-systemd system. --- src/libsystemd/sd-login/sd-login.c | 4 +++- src/libsystemd/sd-login/test-login.c | 3 ++- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/src/libsystemd/sd-login/sd-login.c b/src/libsystemd/sd-login/sd-login.c index cd844b3105..82a94bfd5c 100644 --- a/src/libsystemd/sd-login/sd-login.c +++ b/src/libsystemd/sd-login/sd-login.c @@ -66,11 +66,13 @@ _public_ int sd_pid_get_session(pid_t pid, char **session) { } _public_ int sd_pid_get_unit(pid_t pid, char **unit) { + int r; assert_return(pid >= 0, -EINVAL); assert_return(unit, -EINVAL); - return cg_pid_get_unit(pid, unit); + r = cg_pid_get_unit(pid, unit); + return r == -ENXIO ? -ENODATA : r; } _public_ int sd_pid_get_user_unit(pid_t pid, char **unit) { diff --git a/src/libsystemd/sd-login/test-login.c b/src/libsystemd/sd-login/test-login.c index fb7d4e2ece..6889d2f0b4 100644 --- a/src/libsystemd/sd-login/test-login.c +++ b/src/libsystemd/sd-login/test-login.c @@ -59,7 +59,8 @@ static void test_login(void) { uid_t u, u2; char *t, **seats, **sessions; - assert_se(sd_pid_get_unit(0, &unit) >= 0); + r = sd_pid_get_unit(0, &unit); + assert_se(r >= 0 || r == -ENODATA); log_info("sd_pid_get_unit(0, …) → \"%s\"", unit); r = sd_pid_get_user_unit(0, &user_unit); From 0543105b0fb13e4243b71a78f62f81fb9dde5d51 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Fri, 19 May 2017 07:52:00 -0400 Subject: [PATCH 7/7] sd-login: fix querying machines when machined is not running We should not leak the internal error from missing directory and treat that case the same as no machines. --- src/libsystemd/sd-login/sd-login.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/libsystemd/sd-login/sd-login.c b/src/libsystemd/sd-login/sd-login.c index 82a94bfd5c..25dff7738f 100644 --- a/src/libsystemd/sd-login/sd-login.c +++ b/src/libsystemd/sd-login/sd-login.c @@ -854,6 +854,10 @@ _public_ int sd_get_machine_names(char ***machines) { assert_return(machines, -EINVAL); r = get_files_in_directory("/run/systemd/machines/", &l); + if (r == -ENOENT) { + *machines = NULL; + return 0; + } if (r < 0) return r;