summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLennart Poettering <lennart@poettering.net>2018-08-07 12:08:24 +0200
committerSven Eden <sven.eden@prydeworx.com>2018-10-29 10:18:37 +0100
commit729a2fa913640bea3376d9afc73a9b4bff371085 (patch)
treed232e32f5d9d5a7ca3b9c7b71785ffb39a1575aa
parent11fb2bd433c0f2f4aa9705a4d5327b6fab7daa07 (diff)
logind: add hashtable for finding session by leader PID
This is useful later on, when we quickly want to find the session for a leader PID. (cherry picked from commit 238794b15082e6f61d0ce2943d39205289fff7f0)
-rw-r--r--src/login/logind-core.c16
-rw-r--r--src/login/logind-dbus.c3
-rw-r--r--src/login/logind-session.c41
-rw-r--r--src/login/logind-session.h1
-rw-r--r--src/login/logind.c4
-rw-r--r--src/login/logind.h1
6 files changed, 53 insertions, 13 deletions
diff --git a/src/login/logind-core.c b/src/login/logind-core.c
index c75c96c01..b24bc29c6 100644
--- a/src/login/logind-core.c
+++ b/src/login/logind-core.c
@@ -342,18 +342,20 @@ int manager_get_session_by_pid(Manager *m, pid_t pid, Session **ret) {
return -EINVAL;
#if 0 /// elogind does not support systemd units, but its own session system
- r = cg_pid_get_unit(pid, &unit);
- if (r < 0)
- goto not_found;
-
- s = hashmap_get(m->session_units, unit);
- if (!s)
- goto not_found;
+ s = hashmap_get(m->session_units, unit);
+ if (!s)
+ goto not_found;
+ }
#else
log_debug_elogind("Searching session for PID %u", pid);
r = cg_pid_get_session(pid, &session_name);
if (r < 0)
goto not_found;
+ s = hashmap_get(m->sessions_by_leader, PID_TO_PTR(pid));
+ if (!s) {
+ r = cg_pid_get_unit(pid, &unit);
+ if (r < 0)
+ goto not_found;
s = hashmap_get(m->sessions, session_name);
log_debug_elogind("Session Name \"%s\" -> Session \"%s\"",
diff --git a/src/login/logind-dbus.c b/src/login/logind-dbus.c
index 333eb5a8c..855268a63 100644
--- a/src/login/logind-dbus.c
+++ b/src/login/logind-dbus.c
@@ -784,9 +784,8 @@ static int method_create_session(sd_bus_message *message, void *userdata, sd_bus
goto fail;
session_set_user(session, user);
+ session_set_leader(session, leader);
- session->leader = leader;
- session->audit_id = audit_id;
session->type = t;
session->class = c;
session->remote = remote;
diff --git a/src/login/logind-session.c b/src/login/logind-session.c
index 8c478cb3e..d3bdbebb5 100644
--- a/src/login/logind-session.c
+++ b/src/login/logind-session.c
@@ -124,6 +124,9 @@ Session* session_free(Session *s) {
free(s->scope);
}
+ if (pid_is_valid(s->leader))
+ (void) hashmap_remove_value(s->manager->sessions_by_leader, PID_TO_PTR(s->leader), s);
+
#if 0 /// elogind does not support systemd scope_jobs
free(s->scope_job);
#endif // 0
@@ -154,6 +157,30 @@ void session_set_user(Session *s, User *u) {
user_update_last_session_timer(u);
}
+int session_set_leader(Session *s, pid_t pid) {
+ int r;
+
+ assert(s);
+
+ if (!pid_is_valid(pid))
+ return -EINVAL;
+
+ if (s->leader == pid)
+ return 0;
+
+ r = hashmap_put(s->manager->sessions_by_leader, PID_TO_PTR(pid), s);
+ if (r < 0)
+ return r;
+
+ if (pid_is_valid(s->leader))
+ (void) hashmap_remove_value(s->manager->sessions_by_leader, PID_TO_PTR(s->leader), s);
+
+ s->leader = pid;
+ (void) audit_session_from_pid(pid, &s->audit_id);
+
+ return 1;
+}
+
static void session_save_devices(Session *s, FILE *f) {
SessionDevice *sd;
Iterator i;
@@ -467,8 +494,16 @@ int session_load(Session *s) {
}
if (leader) {
- if (parse_pid(leader, &s->leader) >= 0)
- (void) audit_session_from_pid(s->leader, &s->audit_id);
+ pid_t pid;
+
+ r = parse_pid(leader, &pid);
+ if (r < 0)
+ log_debug_errno(r, "Failed to parse leader PID of session: %s", leader);
+ else {
+ r = session_set_leader(s, pid);
+ if (r < 0)
+ log_warning_errno(r, "Failed to set session leader PID, ignoring: %m");
+ }
}
if (type) {
@@ -953,7 +988,7 @@ int session_get_idle_hint(Session *s, dual_timestamp *t) {
/* For sessions with a leader but no explicitly configured
* tty, let's check the controlling tty of the leader */
- if (s->leader > 0) {
+ if (pid_is_valid(s->leader)) {
r = get_process_ctty_atime(s->leader, &atime);
if (r >= 0)
goto found_atime;
diff --git a/src/login/logind-session.h b/src/login/logind-session.h
index 2a082c111..74cda3c57 100644
--- a/src/login/logind-session.h
+++ b/src/login/logind-session.h
@@ -118,6 +118,7 @@ Session* session_free(Session *s);
DEFINE_TRIVIAL_CLEANUP_FUNC(Session *, session_free);
void session_set_user(Session *s, User *u);
+int session_set_leader(Session *s, pid_t pid);
bool session_may_gc(Session *s, bool drop_not_started);
void session_add_to_gc_queue(Session *s);
int session_activate(Session *s);
diff --git a/src/login/logind.c b/src/login/logind.c
index 7a9f5c577..5320820a5 100644
--- a/src/login/logind.c
+++ b/src/login/logind.c
@@ -61,6 +61,7 @@ static int manager_new(Manager **ret) {
m->devices = hashmap_new(&string_hash_ops);
m->seats = hashmap_new(&string_hash_ops);
m->sessions = hashmap_new(&string_hash_ops);
+ m->sessions_by_leader = hashmap_new(NULL);
m->users = hashmap_new(NULL);
m->inhibitors = hashmap_new(&string_hash_ops);
m->buttons = hashmap_new(&string_hash_ops);
@@ -68,7 +69,7 @@ static int manager_new(Manager **ret) {
m->user_units = hashmap_new(&string_hash_ops);
m->session_units = hashmap_new(&string_hash_ops);
- if (!m->devices || !m->seats || !m->sessions || !m->users || !m->inhibitors || !m->buttons || !m->user_units || !m->session_units)
+ if (!m->devices || !m->seats || !m->sessions || !m->sessions_by_leader || !m->users || !m->inhibitors || !m->buttons || !m->user_units || !m->session_units)
return -ENOMEM;
#if 1 /// elogind needs some more data
@@ -132,6 +133,7 @@ static Manager* manager_unref(Manager *m) {
hashmap_free(m->devices);
hashmap_free(m->seats);
hashmap_free(m->sessions);
+ hashmap_free(m->sessions_by_leader);
hashmap_free(m->users);
hashmap_free(m->inhibitors);
hashmap_free(m->buttons);
diff --git a/src/login/logind.h b/src/login/logind.h
index 5b9e22b9b..111a3dab0 100644
--- a/src/login/logind.h
+++ b/src/login/logind.h
@@ -37,6 +37,7 @@ struct Manager {
Hashmap *devices;
Hashmap *seats;
Hashmap *sessions;
+ Hashmap *sessions_by_leader;
Hashmap *users;
Hashmap *inhibitors;
Hashmap *buttons;