[systemd-devel] [PATCH 2/3] logind: differentiate between session scope opening and closing

Djalal Harouni tixxdz at opendz.org
Wed Jan 22 01:25:52 PST 2014


To get the state of the session, the session_get_state() is used.
This function will check if the session->scope_job is set then it will
automatically return SESSION_OPENING. This is buggy in the context of
session closing:

At logout or D-Bus TerminateSession() fifo_fd is removed:

        =>  session_get_state() == SESSION_CLOSING   (correct)

Then we have session_stop() which calls session_stop_scope(), this
will queue the scope job to be removed and set the session->scope_job

        =>  session_get_state() == SESSION_OPENING   (incorrect)

After the scope job is removed the state will be again correct

        =>  session_get_state() == SESSION_CLOSING   (correct)

To fix this and make sure that the state will always be SESSION_CLOSING
we add a flag that is used to differentiate between SESSION_OPENING and
SESSION_CLOSING when the 'session->scope_job' is set.

The 'scope_opening' flag will be set to true only during real
session opening in session_start_scope() which means that during session
closing it will be false.

And update session_get_state() to check if the 'scope_opening' is true
before returning the SESSION_OPENING, if it is not then SESSION_CLOSING
will be returned which is the correct behaviour.
---
 src/login/logind-session-dbus.c | 3 +++
 src/login/logind-session.c      | 4 +++-
 src/login/logind-session.h      | 1 +
 3 files changed, 7 insertions(+), 1 deletion(-)

diff --git a/src/login/logind-session-dbus.c b/src/login/logind-session-dbus.c
index 72bef4c..51832d6 100644
--- a/src/login/logind-session-dbus.c
+++ b/src/login/logind-session-dbus.c
@@ -669,6 +669,9 @@ int session_send_create_reply(Session *s, sd_bus_error *error, bool opening) {
         if (fifo_fd < 0)
                 return fifo_fd;
 
+        /* Clean this up as soon as we have the fifo_fd */
+        s->scope_opening = false;
+
         /* Update the session state file before we notify the client
          * about the result. */
         session_save(s);
diff --git a/src/login/logind-session.c b/src/login/logind-session.c
index ff0a7a4..ba32146 100644
--- a/src/login/logind-session.c
+++ b/src/login/logind-session.c
@@ -491,6 +491,8 @@ static int session_start_scope(Session *s) {
 
                         free(s->scope_job);
                         s->scope_job = job;
+                        /* session scope is being created */
+                        s->scope_opening = true;
                 }
         }
 
@@ -875,7 +877,7 @@ void session_add_to_gc_queue(Session *s) {
 SessionState session_get_state(Session *s) {
         assert(s);
 
-        if (s->scope_job)
+        if (s->scope_job && s->scope_opening)
                 return SESSION_OPENING;
 
         if (s->fifo_fd < 0)
diff --git a/src/login/logind-session.h b/src/login/logind-session.h
index 0810def..8551cee 100644
--- a/src/login/logind-session.h
+++ b/src/login/logind-session.h
@@ -108,6 +108,7 @@ struct Session {
 
         bool in_gc_queue:1;
         bool started:1;
+        bool scope_opening:1; /* session scope is being created */
 
         sd_bus_message *create_message;
 
-- 
1.8.3.1



More information about the systemd-devel mailing list