logind: introduce a state for session, being one of online, active, closing
online = logged in active = logged in and session is in the fg closing = nominally logged out but some left-over processes still around Related to: https://bugzilla.gnome.org/show_bug.cgi?id=677556
This commit is contained in:
parent
f1a8e221ec
commit
0604381b9d
2
TODO
2
TODO
|
@ -25,6 +25,8 @@ Bugfixes:
|
||||||
|
|
||||||
Features:
|
Features:
|
||||||
|
|
||||||
|
* exclude processes marked with argv[0][0]=@ from the normal service killing too
|
||||||
|
|
||||||
* support rd.luks= kernel cmdline params in cryptsetup generator
|
* support rd.luks= kernel cmdline params in cryptsetup generator
|
||||||
|
|
||||||
* support rd.fstab= kernel cmdline params in fstab generator
|
* support rd.fstab= kernel cmdline params in fstab generator
|
||||||
|
|
|
@ -46,3 +46,8 @@ global:
|
||||||
sd_session_get_class;
|
sd_session_get_class;
|
||||||
sd_session_get_display;
|
sd_session_get_display;
|
||||||
} LIBSYSTEMD_LOGIN_38;
|
} LIBSYSTEMD_LOGIN_38;
|
||||||
|
|
||||||
|
LIBSYSTEMD_LOGIN_186 {
|
||||||
|
global:
|
||||||
|
sd_session_get_state;
|
||||||
|
} LIBSYSTEMD_LOGIN_43;
|
||||||
|
|
|
@ -364,7 +364,7 @@ typedef struct SessionStatusInfo {
|
||||||
pid_t leader;
|
pid_t leader;
|
||||||
const char *type;
|
const char *type;
|
||||||
const char *class;
|
const char *class;
|
||||||
bool active;
|
const char *state;
|
||||||
} SessionStatusInfo;
|
} SessionStatusInfo;
|
||||||
|
|
||||||
typedef struct UserStatusInfo {
|
typedef struct UserStatusInfo {
|
||||||
|
@ -458,8 +458,8 @@ static void print_session_status_info(SessionStatusInfo *i) {
|
||||||
} else if (i->class)
|
} else if (i->class)
|
||||||
printf("\t Class: %s\n", i->class);
|
printf("\t Class: %s\n", i->class);
|
||||||
|
|
||||||
|
if (i->state)
|
||||||
printf("\t Active: %s\n", yes_no(i->active));
|
printf("\t State: %s\n", i->state);
|
||||||
|
|
||||||
if (i->default_control_group) {
|
if (i->default_control_group) {
|
||||||
unsigned c;
|
unsigned c;
|
||||||
|
@ -597,6 +597,8 @@ static int status_property_session(const char *name, DBusMessageIter *iter, Sess
|
||||||
i->type = s;
|
i->type = s;
|
||||||
else if (streq(name, "Class"))
|
else if (streq(name, "Class"))
|
||||||
i->class = s;
|
i->class = s;
|
||||||
|
else if (streq(name, "State"))
|
||||||
|
i->state = s;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -621,8 +623,6 @@ static int status_property_session(const char *name, DBusMessageIter *iter, Sess
|
||||||
|
|
||||||
if (streq(name, "Remote"))
|
if (streq(name, "Remote"))
|
||||||
i->remote = b;
|
i->remote = b;
|
||||||
else if (streq(name, "Active"))
|
|
||||||
i->active = b;
|
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
@ -53,12 +53,13 @@
|
||||||
" <property name=\"Remote\" type=\"b\" access=\"read\"/>\n" \
|
" <property name=\"Remote\" type=\"b\" access=\"read\"/>\n" \
|
||||||
" <property name=\"RemoteHost\" type=\"s\" access=\"read\"/>\n" \
|
" <property name=\"RemoteHost\" type=\"s\" access=\"read\"/>\n" \
|
||||||
" <property name=\"RemoteUser\" type=\"s\" access=\"read\"/>\n" \
|
" <property name=\"RemoteUser\" type=\"s\" access=\"read\"/>\n" \
|
||||||
" <property name=\"Service\" type=\"s\" access=\"read\"/>\n" \
|
" <property name=\"Service\" type=\"s\" access=\"read\"/>\n" \
|
||||||
" <property name=\"Leader\" type=\"u\" access=\"read\"/>\n" \
|
" <property name=\"Leader\" type=\"u\" access=\"read\"/>\n" \
|
||||||
" <property name=\"Audit\" type=\"u\" access=\"read\"/>\n" \
|
" <property name=\"Audit\" type=\"u\" access=\"read\"/>\n" \
|
||||||
" <property name=\"Type\" type=\"s\" access=\"read\"/>\n" \
|
" <property name=\"Type\" type=\"s\" access=\"read\"/>\n" \
|
||||||
" <property name=\"Class\" type=\"s\" access=\"read\"/>\n" \
|
" <property name=\"Class\" type=\"s\" access=\"read\"/>\n" \
|
||||||
" <property name=\"Active\" type=\"b\" access=\"read\"/>\n" \
|
" <property name=\"Active\" type=\"b\" access=\"read\"/>\n" \
|
||||||
|
" <property name=\"State\" type=\"s\" access=\"read\"/>\n" \
|
||||||
" <property name=\"Controllers\" type=\"as\" access=\"read\"/>\n" \
|
" <property name=\"Controllers\" type=\"as\" access=\"read\"/>\n" \
|
||||||
" <property name=\"ResetControllers\" type=\"as\" access=\"read\"/>\n" \
|
" <property name=\"ResetControllers\" type=\"as\" access=\"read\"/>\n" \
|
||||||
" <property name=\"KillProcesses\" type=\"b\" access=\"read\"/>\n" \
|
" <property name=\"KillProcesses\" type=\"b\" access=\"read\"/>\n" \
|
||||||
|
@ -219,6 +220,22 @@ static int bus_session_append_default_cgroup(DBusMessageIter *i, const char *pro
|
||||||
static DEFINE_BUS_PROPERTY_APPEND_ENUM(bus_session_append_type, session_type, SessionType);
|
static DEFINE_BUS_PROPERTY_APPEND_ENUM(bus_session_append_type, session_type, SessionType);
|
||||||
static DEFINE_BUS_PROPERTY_APPEND_ENUM(bus_session_append_class, session_class, SessionClass);
|
static DEFINE_BUS_PROPERTY_APPEND_ENUM(bus_session_append_class, session_class, SessionClass);
|
||||||
|
|
||||||
|
static int bus_session_append_state(DBusMessageIter *i, const char *property, void *data) {
|
||||||
|
Session *s = data;
|
||||||
|
const char *state;
|
||||||
|
|
||||||
|
assert(i);
|
||||||
|
assert(property);
|
||||||
|
assert(s);
|
||||||
|
|
||||||
|
state = session_state_to_string(session_get_state(s));
|
||||||
|
|
||||||
|
if (!dbus_message_iter_append_basic(i, DBUS_TYPE_STRING, &state))
|
||||||
|
return -ENOMEM;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static int get_session_for_path(Manager *m, const char *path, Session **_s) {
|
static int get_session_for_path(Manager *m, const char *path, Session **_s) {
|
||||||
Session *s;
|
Session *s;
|
||||||
char *id;
|
char *id;
|
||||||
|
@ -262,6 +279,7 @@ static const BusProperty bus_login_session_properties[] = {
|
||||||
{ "Type", bus_session_append_type, "s", offsetof(Session, type) },
|
{ "Type", bus_session_append_type, "s", offsetof(Session, type) },
|
||||||
{ "Class", bus_session_append_class, "s", offsetof(Session, class) },
|
{ "Class", bus_session_append_class, "s", offsetof(Session, class) },
|
||||||
{ "Active", bus_session_append_active, "b", 0 },
|
{ "Active", bus_session_append_active, "b", 0 },
|
||||||
|
{ "State", bus_session_append_state, "s", 0 },
|
||||||
{ "Controllers", bus_property_append_strv, "as", offsetof(Session, controllers), true },
|
{ "Controllers", bus_property_append_strv, "as", offsetof(Session, controllers), true },
|
||||||
{ "ResetControllers", bus_property_append_strv, "as", offsetof(Session, reset_controllers), true },
|
{ "ResetControllers", bus_property_append_strv, "as", offsetof(Session, reset_controllers), true },
|
||||||
{ "KillProcesses", bus_property_append_bool, "b", offsetof(Session, kill_processes) },
|
{ "KillProcesses", bus_property_append_bool, "b", offsetof(Session, kill_processes) },
|
||||||
|
|
|
@ -133,11 +133,13 @@ int session_save(Session *s) {
|
||||||
"UID=%lu\n"
|
"UID=%lu\n"
|
||||||
"USER=%s\n"
|
"USER=%s\n"
|
||||||
"ACTIVE=%i\n"
|
"ACTIVE=%i\n"
|
||||||
|
"STATE=%s\n"
|
||||||
"REMOTE=%i\n"
|
"REMOTE=%i\n"
|
||||||
"KILL_PROCESSES=%i\n",
|
"KILL_PROCESSES=%i\n",
|
||||||
(unsigned long) s->user->uid,
|
(unsigned long) s->user->uid,
|
||||||
s->user->name,
|
s->user->name,
|
||||||
session_is_active(s),
|
session_is_active(s),
|
||||||
|
session_state_to_string(session_get_state(s)),
|
||||||
s->remote,
|
s->remote,
|
||||||
s->kill_processes);
|
s->kill_processes);
|
||||||
|
|
||||||
|
@ -913,6 +915,18 @@ void session_add_to_gc_queue(Session *s) {
|
||||||
s->in_gc_queue = true;
|
s->in_gc_queue = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SessionState session_get_state(Session *s) {
|
||||||
|
assert(s);
|
||||||
|
|
||||||
|
if (s->fifo_fd < 0)
|
||||||
|
return SESSION_CLOSING;
|
||||||
|
|
||||||
|
if (session_is_active(s))
|
||||||
|
return SESSION_ACTIVE;
|
||||||
|
|
||||||
|
return SESSION_ONLINE;
|
||||||
|
}
|
||||||
|
|
||||||
int session_kill(Session *s, KillWho who, int signo) {
|
int session_kill(Session *s, KillWho who, int signo) {
|
||||||
int r = 0;
|
int r = 0;
|
||||||
Set *pid_set = NULL;
|
Set *pid_set = NULL;
|
||||||
|
@ -954,6 +968,14 @@ int session_kill(Session *s, KillWho who, int signo) {
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static const char* const session_state_table[_SESSION_TYPE_MAX] = {
|
||||||
|
[SESSION_ONLINE] = "online",
|
||||||
|
[SESSION_ACTIVE] = "active",
|
||||||
|
[SESSION_CLOSING] = "closing"
|
||||||
|
};
|
||||||
|
|
||||||
|
DEFINE_STRING_TABLE_LOOKUP(session_state, SessionState);
|
||||||
|
|
||||||
static const char* const session_type_table[_SESSION_TYPE_MAX] = {
|
static const char* const session_type_table[_SESSION_TYPE_MAX] = {
|
||||||
[SESSION_TTY] = "tty",
|
[SESSION_TTY] = "tty",
|
||||||
[SESSION_X11] = "x11",
|
[SESSION_X11] = "x11",
|
||||||
|
|
|
@ -30,6 +30,14 @@ typedef struct Session Session;
|
||||||
#include "logind-seat.h"
|
#include "logind-seat.h"
|
||||||
#include "logind-user.h"
|
#include "logind-user.h"
|
||||||
|
|
||||||
|
typedef enum SessionState {
|
||||||
|
SESSION_ONLINE, /* Logged in */
|
||||||
|
SESSION_ACTIVE, /* Logged in and in the fg */
|
||||||
|
SESSION_CLOSING, /* Logged out, but processes still remain */
|
||||||
|
_SESSION_STATE_MAX,
|
||||||
|
_SESSION_STATE_INVALID = -1
|
||||||
|
} SessionState;
|
||||||
|
|
||||||
typedef enum SessionType {
|
typedef enum SessionType {
|
||||||
SESSION_UNSPECIFIED,
|
SESSION_UNSPECIFIED,
|
||||||
SESSION_TTY,
|
SESSION_TTY,
|
||||||
|
@ -118,12 +126,17 @@ int session_kill(Session *s, KillWho who, int signo);
|
||||||
|
|
||||||
char *session_bus_path(Session *s);
|
char *session_bus_path(Session *s);
|
||||||
|
|
||||||
|
SessionState session_get_state(Session *u);
|
||||||
|
|
||||||
extern const DBusObjectPathVTable bus_session_vtable;
|
extern const DBusObjectPathVTable bus_session_vtable;
|
||||||
|
|
||||||
int session_send_signal(Session *s, bool new_session);
|
int session_send_signal(Session *s, bool new_session);
|
||||||
int session_send_changed(Session *s, const char *properties);
|
int session_send_changed(Session *s, const char *properties);
|
||||||
int session_send_lock(Session *s, bool lock);
|
int session_send_lock(Session *s, bool lock);
|
||||||
|
|
||||||
|
const char* session_state_to_string(SessionState t);
|
||||||
|
SessionState session_state_from_string(const char *s);
|
||||||
|
|
||||||
const char* session_type_to_string(SessionType t);
|
const char* session_type_to_string(SessionType t);
|
||||||
SessionType session_type_from_string(const char *s);
|
SessionType session_type_from_string(const char *s);
|
||||||
|
|
||||||
|
|
|
@ -30,11 +30,11 @@ typedef struct User User;
|
||||||
#include "logind-session.h"
|
#include "logind-session.h"
|
||||||
|
|
||||||
typedef enum UserState {
|
typedef enum UserState {
|
||||||
USER_OFFLINE,
|
USER_OFFLINE, /* Not logged in at all */
|
||||||
USER_LINGERING,
|
USER_LINGERING, /* Lingering has been enabled by the admin for this user */
|
||||||
USER_ONLINE,
|
USER_ONLINE, /* User logged in */
|
||||||
USER_ACTIVE,
|
USER_ACTIVE, /* User logged in and has a session in the fg */
|
||||||
USER_CLOSING,
|
USER_CLOSING, /* User logged out, but processes still remain and lingering is not enabled */
|
||||||
_USER_STATE_MAX,
|
_USER_STATE_MAX,
|
||||||
_USER_STATE_INVALID = -1
|
_USER_STATE_INVALID = -1
|
||||||
} UserState;
|
} UserState;
|
||||||
|
|
|
@ -317,6 +317,30 @@ _public_ int sd_session_is_active(const char *session) {
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_public_ int sd_session_get_state(const char *session, char **state) {
|
||||||
|
char *p, *s = NULL;
|
||||||
|
int r;
|
||||||
|
|
||||||
|
if (!state)
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
r = file_of_session(session, &p);
|
||||||
|
if (r < 0)
|
||||||
|
return r;
|
||||||
|
|
||||||
|
r = parse_env_file(p, NEWLINE, "STATE", &s, NULL);
|
||||||
|
free(p);
|
||||||
|
|
||||||
|
if (r < 0) {
|
||||||
|
free(s);
|
||||||
|
return r;
|
||||||
|
} else if (!s)
|
||||||
|
return -EIO;
|
||||||
|
|
||||||
|
*state = s;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
_public_ int sd_session_get_uid(const char *session, uid_t *uid) {
|
_public_ int sd_session_get_uid(const char *session, uid_t *uid) {
|
||||||
int r;
|
int r;
|
||||||
char *p, *s = NULL;
|
char *p, *s = NULL;
|
||||||
|
|
|
@ -71,6 +71,11 @@ int main(int argc, char* argv[]) {
|
||||||
assert_se(r >= 0);
|
assert_se(r >= 0);
|
||||||
printf("active = %s\n", yes_no(r));
|
printf("active = %s\n", yes_no(r));
|
||||||
|
|
||||||
|
r = sd_session_get_state(session, &state);
|
||||||
|
assert_se(r >= 0);
|
||||||
|
printf("state = %s\n", state);
|
||||||
|
free(state);
|
||||||
|
|
||||||
assert_se(sd_session_get_uid(session, &u) >= 0);
|
assert_se(sd_session_get_uid(session, &u) >= 0);
|
||||||
printf("uid = %lu\n", (unsigned long) u);
|
printf("uid = %lu\n", (unsigned long) u);
|
||||||
assert_se(u == u2);
|
assert_se(u == u2);
|
||||||
|
|
|
@ -63,7 +63,7 @@ int sd_pid_get_owner_uid(pid_t pid, uid_t *uid);
|
||||||
* error for non-service processes. */
|
* error for non-service processes. */
|
||||||
int sd_pid_get_unit(pid_t, char **unit);
|
int sd_pid_get_unit(pid_t, char **unit);
|
||||||
|
|
||||||
/* Get state from uid. Possible states: offline, lingering, online, active */
|
/* Get state from uid. Possible states: offline, lingering, online, active, closing */
|
||||||
int sd_uid_get_state(uid_t uid, char**state);
|
int sd_uid_get_state(uid_t uid, char**state);
|
||||||
|
|
||||||
/* Return 1 if uid has session on seat. If require_active is true will
|
/* Return 1 if uid has session on seat. If require_active is true will
|
||||||
|
@ -80,9 +80,14 @@ int sd_uid_get_sessions(uid_t uid, int require_active, char ***sessions);
|
||||||
* just return number of seats.*/
|
* just return number of seats.*/
|
||||||
int sd_uid_get_seats(uid_t uid, int require_active, char ***seats);
|
int sd_uid_get_seats(uid_t uid, int require_active, char ***seats);
|
||||||
|
|
||||||
/* Return 1 if the session is a active */
|
/* Return 1 if the session is a active. */
|
||||||
int sd_session_is_active(const char *session);
|
int sd_session_is_active(const char *session);
|
||||||
|
|
||||||
|
/* Get state from session. Possible states: online, active, closing
|
||||||
|
* (This function is a more generic version of
|
||||||
|
* sd_session_is_active().) */
|
||||||
|
int sd_session_get_state(const char *sessio, char **state);
|
||||||
|
|
||||||
/* Determine user id of session */
|
/* Determine user id of session */
|
||||||
int sd_session_get_uid(const char *session, uid_t *uid);
|
int sd_session_get_uid(const char *session, uid_t *uid);
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue