|
|
b7dd4d |
From fbc394252588325b6e7ecd1ab65ad40b51763c58 Mon Sep 17 00:00:00 2001
|
|
|
b7dd4d |
From: Lennart Poettering <lennart@poettering.net>
|
|
|
b7dd4d |
Date: Tue, 7 Aug 2018 12:08:24 +0200
|
|
|
b7dd4d |
Subject: [PATCH] logind: add hashtable for finding session by leader PID
|
|
|
b7dd4d |
|
|
|
b7dd4d |
This is useful later on, when we quickly want to find the session for a
|
|
|
b7dd4d |
leader PID.
|
|
|
b7dd4d |
|
|
|
b7dd4d |
(cherry picked from commit 238794b15082e6f61d0ce2943d39205289fff7f0)
|
|
|
b7dd4d |
|
|
|
b7dd4d |
Related: #2122288
|
|
|
b7dd4d |
---
|
|
|
b7dd4d |
src/login/logind-core.c | 15 ++++++++------
|
|
|
b7dd4d |
src/login/logind-dbus.c | 3 +--
|
|
|
b7dd4d |
src/login/logind-session.c | 41 +++++++++++++++++++++++++++++++++++---
|
|
|
b7dd4d |
src/login/logind-session.h | 1 +
|
|
|
b7dd4d |
src/login/logind.c | 4 +++-
|
|
|
b7dd4d |
src/login/logind.h | 1 +
|
|
|
b7dd4d |
6 files changed, 53 insertions(+), 12 deletions(-)
|
|
|
b7dd4d |
|
|
|
b7dd4d |
diff --git a/src/login/logind-core.c b/src/login/logind-core.c
|
|
|
b7dd4d |
index 7e33f8e6aa..a1943b6f9d 100644
|
|
|
b7dd4d |
--- a/src/login/logind-core.c
|
|
|
b7dd4d |
+++ b/src/login/logind-core.c
|
|
|
b7dd4d |
@@ -339,13 +339,16 @@ int manager_get_session_by_pid(Manager *m, pid_t pid, Session **ret) {
|
|
|
b7dd4d |
if (!pid_is_valid(pid))
|
|
|
b7dd4d |
return -EINVAL;
|
|
|
b7dd4d |
|
|
|
b7dd4d |
- r = cg_pid_get_unit(pid, &unit);
|
|
|
b7dd4d |
- if (r < 0)
|
|
|
b7dd4d |
- goto not_found;
|
|
|
b7dd4d |
+ s = hashmap_get(m->sessions_by_leader, PID_TO_PTR(pid));
|
|
|
b7dd4d |
+ if (!s) {
|
|
|
b7dd4d |
+ r = cg_pid_get_unit(pid, &unit);
|
|
|
b7dd4d |
+ if (r < 0)
|
|
|
b7dd4d |
+ goto not_found;
|
|
|
b7dd4d |
|
|
|
b7dd4d |
- s = hashmap_get(m->session_units, unit);
|
|
|
b7dd4d |
- if (!s)
|
|
|
b7dd4d |
- goto not_found;
|
|
|
b7dd4d |
+ s = hashmap_get(m->session_units, unit);
|
|
|
b7dd4d |
+ if (!s)
|
|
|
b7dd4d |
+ goto not_found;
|
|
|
b7dd4d |
+ }
|
|
|
b7dd4d |
|
|
|
b7dd4d |
if (ret)
|
|
|
b7dd4d |
*ret = s;
|
|
|
b7dd4d |
diff --git a/src/login/logind-dbus.c b/src/login/logind-dbus.c
|
|
|
b7dd4d |
index 0248042308..01bfef4ff7 100644
|
|
|
b7dd4d |
--- a/src/login/logind-dbus.c
|
|
|
b7dd4d |
+++ b/src/login/logind-dbus.c
|
|
|
b7dd4d |
@@ -784,9 +784,8 @@ static int method_create_session(sd_bus_message *message, void *userdata, sd_bus
|
|
|
b7dd4d |
goto fail;
|
|
|
b7dd4d |
|
|
|
b7dd4d |
session_set_user(session, user);
|
|
|
b7dd4d |
+ session_set_leader(session, leader);
|
|
|
b7dd4d |
|
|
|
b7dd4d |
- session->leader = leader;
|
|
|
b7dd4d |
- session->audit_id = audit_id;
|
|
|
b7dd4d |
session->type = t;
|
|
|
b7dd4d |
session->class = c;
|
|
|
b7dd4d |
session->remote = remote;
|
|
|
b7dd4d |
diff --git a/src/login/logind-session.c b/src/login/logind-session.c
|
|
|
b7dd4d |
index d666f86d3f..cc838ca383 100644
|
|
|
b7dd4d |
--- a/src/login/logind-session.c
|
|
|
b7dd4d |
+++ b/src/login/logind-session.c
|
|
|
b7dd4d |
@@ -121,6 +121,9 @@ Session* session_free(Session *s) {
|
|
|
b7dd4d |
free(s->scope);
|
|
|
b7dd4d |
}
|
|
|
b7dd4d |
|
|
|
b7dd4d |
+ if (pid_is_valid(s->leader))
|
|
|
b7dd4d |
+ (void) hashmap_remove_value(s->manager->sessions_by_leader, PID_TO_PTR(s->leader), s);
|
|
|
b7dd4d |
+
|
|
|
b7dd4d |
free(s->scope_job);
|
|
|
b7dd4d |
|
|
|
b7dd4d |
sd_bus_message_unref(s->create_message);
|
|
|
b7dd4d |
@@ -149,6 +152,30 @@ void session_set_user(Session *s, User *u) {
|
|
|
b7dd4d |
user_update_last_session_timer(u);
|
|
|
b7dd4d |
}
|
|
|
b7dd4d |
|
|
|
b7dd4d |
+int session_set_leader(Session *s, pid_t pid) {
|
|
|
b7dd4d |
+ int r;
|
|
|
b7dd4d |
+
|
|
|
b7dd4d |
+ assert(s);
|
|
|
b7dd4d |
+
|
|
|
b7dd4d |
+ if (!pid_is_valid(pid))
|
|
|
b7dd4d |
+ return -EINVAL;
|
|
|
b7dd4d |
+
|
|
|
b7dd4d |
+ if (s->leader == pid)
|
|
|
b7dd4d |
+ return 0;
|
|
|
b7dd4d |
+
|
|
|
b7dd4d |
+ r = hashmap_put(s->manager->sessions_by_leader, PID_TO_PTR(pid), s);
|
|
|
b7dd4d |
+ if (r < 0)
|
|
|
b7dd4d |
+ return r;
|
|
|
b7dd4d |
+
|
|
|
b7dd4d |
+ if (pid_is_valid(s->leader))
|
|
|
b7dd4d |
+ (void) hashmap_remove_value(s->manager->sessions_by_leader, PID_TO_PTR(s->leader), s);
|
|
|
b7dd4d |
+
|
|
|
b7dd4d |
+ s->leader = pid;
|
|
|
b7dd4d |
+ (void) audit_session_from_pid(pid, &s->audit_id);
|
|
|
b7dd4d |
+
|
|
|
b7dd4d |
+ return 1;
|
|
|
b7dd4d |
+}
|
|
|
b7dd4d |
+
|
|
|
b7dd4d |
static void session_save_devices(Session *s, FILE *f) {
|
|
|
b7dd4d |
SessionDevice *sd;
|
|
|
b7dd4d |
Iterator i;
|
|
|
b7dd4d |
@@ -473,8 +500,16 @@ int session_load(Session *s) {
|
|
|
b7dd4d |
}
|
|
|
b7dd4d |
|
|
|
b7dd4d |
if (leader) {
|
|
|
b7dd4d |
- if (parse_pid(leader, &s->leader) >= 0)
|
|
|
b7dd4d |
- (void) audit_session_from_pid(s->leader, &s->audit_id);
|
|
|
b7dd4d |
+ pid_t pid;
|
|
|
b7dd4d |
+
|
|
|
b7dd4d |
+ r = parse_pid(leader, &pid;;
|
|
|
b7dd4d |
+ if (r < 0)
|
|
|
b7dd4d |
+ log_debug_errno(r, "Failed to parse leader PID of session: %s", leader);
|
|
|
b7dd4d |
+ else {
|
|
|
b7dd4d |
+ r = session_set_leader(s, pid);
|
|
|
b7dd4d |
+ if (r < 0)
|
|
|
b7dd4d |
+ log_warning_errno(r, "Failed to set session leader PID, ignoring: %m");
|
|
|
b7dd4d |
+ }
|
|
|
b7dd4d |
}
|
|
|
b7dd4d |
|
|
|
b7dd4d |
if (type) {
|
|
|
b7dd4d |
@@ -910,7 +945,7 @@ int session_get_idle_hint(Session *s, dual_timestamp *t) {
|
|
|
b7dd4d |
|
|
|
b7dd4d |
/* For sessions with a leader but no explicitly configured
|
|
|
b7dd4d |
* tty, let's check the controlling tty of the leader */
|
|
|
b7dd4d |
- if (s->leader > 0) {
|
|
|
b7dd4d |
+ if (pid_is_valid(s->leader)) {
|
|
|
b7dd4d |
r = get_process_ctty_atime(s->leader, &atime);
|
|
|
b7dd4d |
if (r >= 0)
|
|
|
b7dd4d |
goto found_atime;
|
|
|
b7dd4d |
diff --git a/src/login/logind-session.h b/src/login/logind-session.h
|
|
|
b7dd4d |
index 7da845cea3..8c7d0301f2 100644
|
|
|
b7dd4d |
--- a/src/login/logind-session.h
|
|
|
b7dd4d |
+++ b/src/login/logind-session.h
|
|
|
b7dd4d |
@@ -124,6 +124,7 @@ Session* session_free(Session *s);
|
|
|
b7dd4d |
DEFINE_TRIVIAL_CLEANUP_FUNC(Session *, session_free);
|
|
|
b7dd4d |
|
|
|
b7dd4d |
void session_set_user(Session *s, User *u);
|
|
|
b7dd4d |
+int session_set_leader(Session *s, pid_t pid);
|
|
|
b7dd4d |
bool session_may_gc(Session *s, bool drop_not_started);
|
|
|
b7dd4d |
void session_add_to_gc_queue(Session *s);
|
|
|
b7dd4d |
int session_activate(Session *s);
|
|
|
b7dd4d |
diff --git a/src/login/logind.c b/src/login/logind.c
|
|
|
b7dd4d |
index 25de9a6ab2..6b576dad0d 100644
|
|
|
b7dd4d |
--- a/src/login/logind.c
|
|
|
b7dd4d |
+++ b/src/login/logind.c
|
|
|
b7dd4d |
@@ -46,6 +46,7 @@ static int manager_new(Manager **ret) {
|
|
|
b7dd4d |
m->devices = hashmap_new(&string_hash_ops);
|
|
|
b7dd4d |
m->seats = hashmap_new(&string_hash_ops);
|
|
|
b7dd4d |
m->sessions = hashmap_new(&string_hash_ops);
|
|
|
b7dd4d |
+ m->sessions_by_leader = hashmap_new(NULL);
|
|
|
b7dd4d |
m->users = hashmap_new(NULL);
|
|
|
b7dd4d |
m->inhibitors = hashmap_new(&string_hash_ops);
|
|
|
b7dd4d |
m->buttons = hashmap_new(&string_hash_ops);
|
|
|
b7dd4d |
@@ -53,7 +54,7 @@ static int manager_new(Manager **ret) {
|
|
|
b7dd4d |
m->user_units = hashmap_new(&string_hash_ops);
|
|
|
b7dd4d |
m->session_units = hashmap_new(&string_hash_ops);
|
|
|
b7dd4d |
|
|
|
b7dd4d |
- if (!m->devices || !m->seats || !m->sessions || !m->users || !m->inhibitors || !m->buttons || !m->user_units || !m->session_units)
|
|
|
b7dd4d |
+ if (!m->devices || !m->seats || !m->sessions || !m->sessions_by_leader || !m->users || !m->inhibitors || !m->buttons || !m->user_units || !m->session_units)
|
|
|
b7dd4d |
return -ENOMEM;
|
|
|
b7dd4d |
|
|
|
b7dd4d |
m->udev = udev_new();
|
|
|
b7dd4d |
@@ -112,6 +113,7 @@ static Manager* manager_unref(Manager *m) {
|
|
|
b7dd4d |
hashmap_free(m->devices);
|
|
|
b7dd4d |
hashmap_free(m->seats);
|
|
|
b7dd4d |
hashmap_free(m->sessions);
|
|
|
b7dd4d |
+ hashmap_free(m->sessions_by_leader);
|
|
|
b7dd4d |
hashmap_free(m->users);
|
|
|
b7dd4d |
hashmap_free(m->inhibitors);
|
|
|
b7dd4d |
hashmap_free(m->buttons);
|
|
|
b7dd4d |
diff --git a/src/login/logind.h b/src/login/logind.h
|
|
|
b7dd4d |
index bb127bf4a5..7f94dea2f6 100644
|
|
|
b7dd4d |
--- a/src/login/logind.h
|
|
|
b7dd4d |
+++ b/src/login/logind.h
|
|
|
b7dd4d |
@@ -26,6 +26,7 @@ struct Manager {
|
|
|
b7dd4d |
Hashmap *devices;
|
|
|
b7dd4d |
Hashmap *seats;
|
|
|
b7dd4d |
Hashmap *sessions;
|
|
|
b7dd4d |
+ Hashmap *sessions_by_leader;
|
|
|
b7dd4d |
Hashmap *users;
|
|
|
b7dd4d |
Hashmap *inhibitors;
|
|
|
b7dd4d |
Hashmap *buttons;
|