summaryrefslogtreecommitdiff
path: root/src/login
diff options
context:
space:
mode:
authorMichael Biebl <biebl@debian.org>2018-03-06 20:13:05 +0100
committerMichael Biebl <biebl@debian.org>2018-03-06 20:13:05 +0100
commit98393f852f2f66a74f7370aa63c07b26d610343c (patch)
tree627d6c5463c0e6ac9f4f6243a9c9274acdae197d /src/login
parent1d42b86df9052528a8f56b2f52d8bc2faf87b2da (diff)
downloadsystemd-98393f852f2f66a74f7370aa63c07b26d610343c.tar.gz
New upstream version 238
Diffstat (limited to 'src/login')
-rw-r--r--src/login/70-uaccess.rules2
-rw-r--r--src/login/inhibit.c1
-rw-r--r--src/login/logind-acl.c2
-rw-r--r--src/login/logind-button.c6
-rw-r--r--src/login/logind-core.c34
-rw-r--r--src/login/logind-dbus.c24
-rw-r--r--src/login/logind-gperf.gperf1
-rw-r--r--src/login/logind-seat.c8
-rw-r--r--src/login/logind-seat.h2
-rw-r--r--src/login/logind-session-device.c135
-rw-r--r--src/login/logind-session-device.h6
-rw-r--r--src/login/logind-session.c14
-rw-r--r--src/login/logind-session.h2
-rw-r--r--src/login/logind-user.c14
-rw-r--r--src/login/logind-user.h2
-rw-r--r--src/login/logind.c39
-rw-r--r--src/login/logind.conf.in1
-rw-r--r--src/login/logind.h3
-rw-r--r--src/login/meson.build11
-rw-r--r--src/login/org.freedesktop.login1.policy (renamed from src/login/org.freedesktop.login1.policy.in)128
20 files changed, 245 insertions, 190 deletions
diff --git a/src/login/70-uaccess.rules b/src/login/70-uaccess.rules
index f2c838f353..3515d292ac 100644
--- a/src/login/70-uaccess.rules
+++ b/src/login/70-uaccess.rules
@@ -27,7 +27,7 @@ SUBSYSTEM=="block", ENV{ID_CDROM}=="1", TAG+="uaccess"
SUBSYSTEM=="scsi_generic", SUBSYSTEMS=="scsi", ATTRS{type}=="4|5", TAG+="uaccess"
# Sound devices
-SUBSYSTEM=="sound", TAG+="uaccess" \
+SUBSYSTEM=="sound", TAG+="uaccess", \
OPTIONS+="static_node=snd/timer", OPTIONS+="static_node=snd/seq"
# ffado is an userspace driver for firewire sound cards
diff --git a/src/login/inhibit.c b/src/login/inhibit.c
index 22657f9eda..6b5d9c29b9 100644
--- a/src/login/inhibit.c
+++ b/src/login/inhibit.c
@@ -272,6 +272,7 @@ int main(int argc, char *argv[]) {
if (r == 0) {
/* Child */
execvp(argv[optind], argv + optind);
+ log_open();
log_error_errno(errno, "Failed to execute %s: %m", argv[optind]);
_exit(EXIT_FAILURE);
}
diff --git a/src/login/logind-acl.c b/src/login/logind-acl.c
index d785f67ca3..3f355e7ea8 100644
--- a/src/login/logind-acl.c
+++ b/src/login/logind-acl.c
@@ -192,7 +192,7 @@ int devnode_acl_all(struct udev *udev,
assert(udev);
- nodes = set_new(&string_hash_ops);
+ nodes = set_new(&path_hash_ops);
if (!nodes)
return -ENOMEM;
diff --git a/src/login/logind-button.c b/src/login/logind-button.c
index 94945f0bcb..2da6e69952 100644
--- a/src/login/logind-button.c
+++ b/src/login/logind-button.c
@@ -110,9 +110,13 @@ static void button_lid_switch_handle_action(Manager *manager, bool is_edge) {
assert(manager);
- /* If we are docked, handle the lid switch differently */
+ /* If we are docked or on external power, handle the lid switch
+ * differently */
if (manager_is_docked_or_external_displays(manager))
handle_action = manager->handle_lid_switch_docked;
+ else if (manager->handle_lid_switch_ep != _HANDLE_ACTION_INVALID &&
+ manager_is_on_external_power())
+ handle_action = manager->handle_lid_switch_ep;
else
handle_action = manager->handle_lid_switch;
diff --git a/src/login/logind-core.c b/src/login/logind-core.c
index e338682f41..41b4d4d8d7 100644
--- a/src/login/logind-core.c
+++ b/src/login/logind-core.c
@@ -602,3 +602,37 @@ bool manager_is_docked_or_external_displays(Manager *m) {
return false;
}
+
+bool manager_is_on_external_power(void) {
+ int r;
+
+ /* For now we only check for AC power, but 'external power' can apply
+ * to anything that isn't an internal battery */
+ r = on_ac_power();
+ if (r < 0)
+ log_warning_errno(r, "Failed to read AC power status: %m");
+ else if (r > 0)
+ return true;
+
+ return false;
+}
+
+bool manager_all_buttons_ignored(Manager *m) {
+ assert(m);
+
+ if (m->handle_power_key != HANDLE_IGNORE)
+ return false;
+ if (m->handle_suspend_key != HANDLE_IGNORE)
+ return false;
+ if (m->handle_hibernate_key != HANDLE_IGNORE)
+ return false;
+ if (m->handle_lid_switch != HANDLE_IGNORE)
+ return false;
+ if (m->handle_lid_switch_ep != _HANDLE_ACTION_INVALID &&
+ m->handle_lid_switch_ep != HANDLE_IGNORE)
+ return false;
+ if (m->handle_lid_switch_docked != HANDLE_IGNORE)
+ return false;
+
+ return true;
+}
diff --git a/src/login/logind-dbus.c b/src/login/logind-dbus.c
index ae36ececb5..07cb257151 100644
--- a/src/login/logind-dbus.c
+++ b/src/login/logind-dbus.c
@@ -41,6 +41,7 @@
#include "mkdir.h"
#include "path-util.h"
#include "process-util.h"
+#include "cgroup-util.h"
#include "selinux-util.h"
#include "sleep-config.h"
#include "special.h"
@@ -658,6 +659,7 @@ static int method_list_inhibitors(sd_bus_message *message, void *userdata, sd_bu
static int method_create_session(sd_bus_message *message, void *userdata, sd_bus_error *error) {
const char *service, *type, *class, *cseat, *tty, *display, *remote_user, *remote_host, *desktop;
uint32_t audit_id = 0;
+ _cleanup_free_ char *unit = NULL;
_cleanup_free_ char *id = NULL;
Session *session = NULL;
Manager *m = userdata;
@@ -787,8 +789,15 @@ static int method_create_session(sd_bus_message *message, void *userdata, sd_bus
return r;
}
- r = manager_get_session_by_pid(m, leader, NULL);
- if (r > 0)
+ /*
+ * Check if we are already in a logind session. Or if we are in user@.service
+ * which is a special PAM session that avoids creating a logind session.
+ */
+ r = cg_pid_get_unit(leader, &unit);
+ if (r < 0)
+ return r;
+ if (hashmap_get(m->session_units, unit) ||
+ hashmap_get(m->user_units, unit))
return sd_bus_error_setf(error, BUS_ERROR_SESSION_BUSY, "Already running in a session");
/*
@@ -1930,15 +1939,11 @@ static int nologin_timeout_handler(
void *userdata) {
Manager *m = userdata;
- int r;
log_info("Creating /run/nologin, blocking further logins...");
- r = write_string_file_atomic_label("/run/nologin", "System is going down.");
- if (r < 0)
- log_error_errno(r, "Failed to create /run/nologin: %m");
- else
- m->unlink_nologin = true;
+ m->unlink_nologin =
+ create_shutdown_run_nologin_or_warn() >= 0;
return 0;
}
@@ -2010,7 +2015,7 @@ static void reset_scheduled_shutdown(Manager *m) {
m->shutdown_dry_run = false;
if (m->unlink_nologin) {
- (void) unlink("/run/nologin");
+ (void) unlink_or_warn("/run/nologin");
m->unlink_nologin = false;
}
@@ -2653,6 +2658,7 @@ const sd_bus_vtable manager_vtable[] = {
SD_BUS_PROPERTY("HandleSuspendKey", "s", property_get_handle_action, offsetof(Manager, handle_suspend_key), SD_BUS_VTABLE_PROPERTY_CONST),
SD_BUS_PROPERTY("HandleHibernateKey", "s", property_get_handle_action, offsetof(Manager, handle_hibernate_key), SD_BUS_VTABLE_PROPERTY_CONST),
SD_BUS_PROPERTY("HandleLidSwitch", "s", property_get_handle_action, offsetof(Manager, handle_lid_switch), SD_BUS_VTABLE_PROPERTY_CONST),
+ SD_BUS_PROPERTY("HandleLidSwitchExternalPower", "s", property_get_handle_action, offsetof(Manager, handle_lid_switch_ep), SD_BUS_VTABLE_PROPERTY_CONST),
SD_BUS_PROPERTY("HandleLidSwitchDocked", "s", property_get_handle_action, offsetof(Manager, handle_lid_switch_docked), SD_BUS_VTABLE_PROPERTY_CONST),
SD_BUS_PROPERTY("HoldoffTimeoutUSec", "t", NULL, offsetof(Manager, holdoff_timeout_usec), SD_BUS_VTABLE_PROPERTY_CONST),
SD_BUS_PROPERTY("IdleAction", "s", property_get_handle_action, offsetof(Manager, idle_action), SD_BUS_VTABLE_PROPERTY_CONST),
diff --git a/src/login/logind-gperf.gperf b/src/login/logind-gperf.gperf
index ee62db63a5..f6f57526f6 100644
--- a/src/login/logind-gperf.gperf
+++ b/src/login/logind-gperf.gperf
@@ -27,6 +27,7 @@ Login.HandlePowerKey, config_parse_handle_action, 0, offsetof(Manag
Login.HandleSuspendKey, config_parse_handle_action, 0, offsetof(Manager, handle_suspend_key)
Login.HandleHibernateKey, config_parse_handle_action, 0, offsetof(Manager, handle_hibernate_key)
Login.HandleLidSwitch, config_parse_handle_action, 0, offsetof(Manager, handle_lid_switch)
+Login.HandleLidSwitchExternalPower,config_parse_handle_action, 0, offsetof(Manager, handle_lid_switch_ep)
Login.HandleLidSwitchDocked, config_parse_handle_action, 0, offsetof(Manager, handle_lid_switch_docked)
Login.PowerKeyIgnoreInhibited, config_parse_bool, 0, offsetof(Manager, power_key_ignore_inhibited)
Login.SuspendKeyIgnoreInhibited, config_parse_bool, 0, offsetof(Manager, suspend_key_ignore_inhibited)
diff --git a/src/login/logind-seat.c b/src/login/logind-seat.c
index b99e7abf91..46e7c06ddc 100644
--- a/src/login/logind-seat.c
+++ b/src/login/logind-seat.c
@@ -639,16 +639,16 @@ int seat_get_idle_hint(Seat *s, dual_timestamp *t) {
return idle_hint;
}
-bool seat_check_gc(Seat *s, bool drop_not_started) {
+bool seat_may_gc(Seat *s, bool drop_not_started) {
assert(s);
if (drop_not_started && !s->started)
- return false;
+ return true;
if (seat_is_seat0(s))
- return true;
+ return false;
- return seat_has_master_device(s);
+ return !seat_has_master_device(s);
}
void seat_add_to_gc_queue(Seat *s) {
diff --git a/src/login/logind-seat.h b/src/login/logind-seat.h
index 5427ac21c8..4982ea3381 100644
--- a/src/login/logind-seat.h
+++ b/src/login/logind-seat.h
@@ -79,7 +79,7 @@ int seat_start(Seat *s);
int seat_stop(Seat *s, bool force);
int seat_stop_sessions(Seat *s, bool force);
-bool seat_check_gc(Seat *s, bool drop_not_started);
+bool seat_may_gc(Seat *s, bool drop_not_started);
void seat_add_to_gc_queue(Seat *s);
bool seat_name_is_valid(const char *name);
diff --git a/src/login/logind-session-device.c b/src/login/logind-session-device.c
index 067e67a93d..73eee72515 100644
--- a/src/login/logind-session-device.c
+++ b/src/login/logind-session-device.c
@@ -74,20 +74,25 @@ static int session_device_notify(SessionDevice *sd, enum SessionDeviceNotificati
return r;
switch (type) {
+
case SESSION_DEVICE_RESUME:
r = sd_bus_message_append(m, "uuh", major, minor, sd->fd);
if (r < 0)
return r;
break;
+
case SESSION_DEVICE_TRY_PAUSE:
t = "pause";
break;
+
case SESSION_DEVICE_PAUSE:
t = "force";
break;
+
case SESSION_DEVICE_RELEASE:
t = "gone";
break;
+
default:
return -EINVAL;
}
@@ -101,43 +106,33 @@ static int session_device_notify(SessionDevice *sd, enum SessionDeviceNotificati
return sd_bus_send(sd->session->manager->bus, m, NULL);
}
-static int sd_eviocrevoke(int fd) {
- static bool warned;
- int r;
+static void sd_eviocrevoke(int fd) {
+ static bool warned = false;
assert(fd >= 0);
- r = ioctl(fd, EVIOCREVOKE, NULL);
- if (r < 0) {
- r = -errno;
- if (r == -EINVAL && !warned) {
+ if (ioctl(fd, EVIOCREVOKE, NULL) < 0) {
+
+ if (errno == EINVAL && !warned) {
+ log_warning_errno(errno, "Kernel does not support evdev-revocation: %m");
warned = true;
- log_warning("kernel does not support evdev-revocation");
}
}
-
- return 0;
}
static int sd_drmsetmaster(int fd) {
- int r;
-
assert(fd >= 0);
- r = ioctl(fd, DRM_IOCTL_SET_MASTER, 0);
- if (r < 0)
+ if (ioctl(fd, DRM_IOCTL_SET_MASTER, 0) < 0)
return -errno;
return 0;
}
static int sd_drmdropmaster(int fd) {
- int r;
-
assert(fd >= 0);
- r = ioctl(fd, DRM_IOCTL_DROP_MASTER, 0);
- if (r < 0)
+ if (ioctl(fd, DRM_IOCTL_DROP_MASTER, 0) < 0)
return -errno;
return 0;
@@ -146,7 +141,9 @@ static int sd_drmdropmaster(int fd) {
static int session_device_open(SessionDevice *sd, bool active) {
int fd, r;
+ assert(sd);
assert(sd->type != DEVICE_TYPE_UNKNOWN);
+ assert(sd->node);
/* open device and try to get an udev_device from it */
fd = open(sd->node, O_RDWR|O_CLOEXEC|O_NOCTTY|O_NONBLOCK);
@@ -154,28 +151,27 @@ static int session_device_open(SessionDevice *sd, bool active) {
return -errno;
switch (sd->type) {
+
case DEVICE_TYPE_DRM:
if (active) {
- /* Weird legacy DRM semantics might return an error
- * even though we're master. No way to detect that so
- * fail at all times and let caller retry in inactive
- * state. */
+ /* Weird legacy DRM semantics might return an error even though we're master. No way to detect
+ * that so fail at all times and let caller retry in inactive state. */
r = sd_drmsetmaster(fd);
if (r < 0) {
close_nointr(fd);
return r;
}
- } else {
- /* DRM-Master is granted to the first user who opens a
- * device automatically (ughh, racy!). Hence, we just
- * drop DRM-Master in case we were the first. */
- sd_drmdropmaster(fd);
- }
+ } else
+ /* DRM-Master is granted to the first user who opens a device automatically (ughh,
+ * racy!). Hence, we just drop DRM-Master in case we were the first. */
+ (void) sd_drmdropmaster(fd);
break;
+
case DEVICE_TYPE_EVDEV:
if (!active)
sd_eviocrevoke(fd);
break;
+
case DEVICE_TYPE_UNKNOWN:
default:
/* fallback for devices wihout synchronizations */
@@ -195,29 +191,38 @@ static int session_device_start(SessionDevice *sd) {
return 0;
switch (sd->type) {
+
case DEVICE_TYPE_DRM:
- /* Device is kept open. Simply call drmSetMaster() and hope
- * there is no-one else. In case it fails, we keep the device
- * paused. Maybe at some point we have a drmStealMaster(). */
- r = sd_drmsetmaster(sd->fd);
- if (r < 0)
- return r;
+
+ if (sd->fd < 0) {
+ /* Open device if it isn't open yet */
+ sd->fd = session_device_open(sd, true);
+ if (sd->fd < 0)
+ return sd->fd;
+ } else {
+ /* Device is kept open. Simply call drmSetMaster() and hope there is no-one else. In case it fails, we
+ * keep the device paused. Maybe at some point we have a drmStealMaster(). */
+ r = sd_drmsetmaster(sd->fd);
+ if (r < 0)
+ return r;
+ }
break;
+
case DEVICE_TYPE_EVDEV:
- /* Evdev devices are revoked while inactive. Reopen it and we
- * are fine. */
+ /* Evdev devices are revoked while inactive. Reopen it and we are fine. */
r = session_device_open(sd, true);
if (r < 0)
return r;
- /* For evdev devices, the file descriptor might be left
- * uninitialized. This might happen while resuming into a
- * session and logind has been restarted right before. */
+
+ /* For evdev devices, the file descriptor might be left uninitialized. This might happen while resuming
+ * into a session and logind has been restarted right before. */
safe_close(sd->fd);
sd->fd = r;
break;
+
case DEVICE_TYPE_UNKNOWN:
default:
- /* fallback for devices wihout synchronizations */
+ /* fallback for devices without synchronizations */
break;
}
@@ -232,6 +237,7 @@ static void session_device_stop(SessionDevice *sd) {
return;
switch (sd->type) {
+
case DEVICE_TYPE_DRM:
/* On DRM devices we simply drop DRM-Master but keep it open.
* This allows the user to keep resources allocated. The
@@ -239,6 +245,7 @@ static void session_device_stop(SessionDevice *sd) {
* circumventing this. */
sd_drmdropmaster(sd->fd);
break;
+
case DEVICE_TYPE_EVDEV:
/* Revoke access on evdev file-descriptors during deactivation.
* This will basically prevent any operations on the fd and
@@ -246,6 +253,7 @@ static void session_device_stop(SessionDevice *sd) {
* protection this way. */
sd_eviocrevoke(sd->fd);
break;
+
case DEVICE_TYPE_UNKNOWN:
default:
/* fallback for devices without synchronization */
@@ -371,10 +379,8 @@ int session_device_new(Session *s, dev_t dev, bool open_device, SessionDevice **
goto error;
r = hashmap_put(s->devices, &sd->dev, sd);
- if (r < 0) {
- r = -ENOMEM;
+ if (r < 0)
goto error;
- }
if (open_device) {
/* Open the device for the first time. We need a valid fd to pass back
@@ -423,7 +429,7 @@ void session_device_free(SessionDevice *sd) {
session_device_stop(sd);
session_device_notify(sd, SESSION_DEVICE_RELEASE);
- close_nointr(sd->fd);
+ safe_close(sd->fd);
LIST_REMOVE(sd_by_device, sd->device->session_devices, sd);
@@ -458,13 +464,15 @@ void session_device_resume_all(Session *s) {
assert(s);
HASHMAP_FOREACH(sd, s->devices, i) {
- if (!sd->active) {
- if (session_device_start(sd) < 0)
- continue;
- if (session_device_save(sd) < 0)
- continue;
- session_device_notify(sd, SESSION_DEVICE_RESUME);
- }
+ if (sd->active)
+ continue;
+
+ if (session_device_start(sd) < 0)
+ continue;
+ if (session_device_save(sd) < 0)
+ continue;
+
+ session_device_notify(sd, SESSION_DEVICE_RESUME);
}
}
@@ -475,25 +483,27 @@ void session_device_pause_all(Session *s) {
assert(s);
HASHMAP_FOREACH(sd, s->devices, i) {
- if (sd->active) {
- session_device_stop(sd);
- session_device_notify(sd, SESSION_DEVICE_PAUSE);
- }
+ if (!sd->active)
+ continue;
+
+ session_device_stop(sd);
+ session_device_notify(sd, SESSION_DEVICE_PAUSE);
}
}
unsigned int session_device_try_pause_all(Session *s) {
+ unsigned num_pending = 0;
SessionDevice *sd;
Iterator i;
- unsigned int num_pending = 0;
assert(s);
HASHMAP_FOREACH(sd, s->devices, i) {
- if (sd->active) {
- session_device_notify(sd, SESSION_DEVICE_TRY_PAUSE);
- ++num_pending;
- }
+ if (!sd->active)
+ continue;
+
+ session_device_notify(sd, SESSION_DEVICE_TRY_PAUSE);
+ num_pending++;
}
return num_pending;
@@ -516,7 +526,7 @@ int session_device_save(SessionDevice *sd) {
return 0;
m = strjoina("FDSTORE=1\n"
- "FDNAME=session", sd->session->id);
+ "FDNAME=session-", sd->session->id);
r = sd_pid_notify_with_fds(0, false, m, &sd->fd, 1);
if (r < 0)
@@ -527,11 +537,12 @@ int session_device_save(SessionDevice *sd) {
}
void session_device_attach_fd(SessionDevice *sd, int fd, bool active) {
- assert(fd > 0);
+ assert(fd >= 0);
assert(sd);
assert(sd->fd < 0);
assert(!sd->active);
sd->fd = fd;
+ sd->pushed_fd = true;
sd->active = active;
}
diff --git a/src/login/logind-session-device.h b/src/login/logind-session-device.h
index a1cf17af92..a9ead7bdca 100644
--- a/src/login/logind-session-device.h
+++ b/src/login/logind-session-device.h
@@ -39,9 +39,9 @@ struct SessionDevice {
dev_t dev;
char *node;
int fd;
- bool active;
- DeviceType type;
- bool pushed_fd;
+ DeviceType type:3;
+ bool active:1;
+ bool pushed_fd:1;
LIST_FIELDS(struct SessionDevice, sd_by_device);
};
diff --git a/src/login/logind-session.c b/src/login/logind-session.c
index 92eb2943fe..1859150b5e 100644
--- a/src/login/logind-session.c
+++ b/src/login/logind-session.c
@@ -1000,27 +1000,27 @@ static void session_remove_fifo(Session *s) {
}
}
-bool session_check_gc(Session *s, bool drop_not_started) {
+bool session_may_gc(Session *s, bool drop_not_started) {
assert(s);
if (drop_not_started && !s->started)
- return false;
+ return true;
if (!s->user)
- return false;
+ return true;
if (s->fifo_fd >= 0) {
if (pipe_eof(s->fifo_fd) <= 0)
- return true;
+ return false;
}
if (s->scope_job && manager_job_is_active(s->manager, s->scope_job))
- return true;
+ return false;
if (s->scope && manager_unit_is_active(s->manager, s->scope))
- return true;
+ return false;
- return false;
+ return true;
}
void session_add_to_gc_queue(Session *s) {
diff --git a/src/login/logind-session.h b/src/login/logind-session.h
index 8491832402..16a278c792 100644
--- a/src/login/logind-session.h
+++ b/src/login/logind-session.h
@@ -131,7 +131,7 @@ struct Session {
Session *session_new(Manager *m, const char *id);
void session_free(Session *s);
void session_set_user(Session *s, User *u);
-bool session_check_gc(Session *s, bool drop_not_started);
+bool session_may_gc(Session *s, bool drop_not_started);
void session_add_to_gc_queue(Session *s);
int session_activate(Session *s);
bool session_is_active(Session *s);
diff --git a/src/login/logind-user.c b/src/login/logind-user.c
index 32b2045696..f85564f221 100644
--- a/src/login/logind-user.c
+++ b/src/login/logind-user.c
@@ -680,25 +680,25 @@ int user_check_linger_file(User *u) {
return access(p, F_OK) >= 0;
}
-bool user_check_gc(User *u, bool drop_not_started) {
+bool user_may_gc(User *u, bool drop_not_started) {
assert(u);
if (drop_not_started && !u->started)
- return false;
+ return true;
if (u->sessions)
- return true;
+ return false;
if (user_check_linger_file(u) > 0)
- return true;
+ return false;
if (u->slice_job && manager_job_is_active(u->manager, u->slice_job))
- return true;
+ return false;
if (u->service_job && manager_job_is_active(u->manager, u->service_job))
- return true;
+ return false;
- return false;
+ return true;
}
void user_add_to_gc_queue(User *u) {
diff --git a/src/login/logind-user.h b/src/login/logind-user.h
index ad1686ffc5..c3452dcd08 100644
--- a/src/login/logind-user.h
+++ b/src/login/logind-user.h
@@ -66,7 +66,7 @@ User *user_free(User *u);
DEFINE_TRIVIAL_CLEANUP_FUNC(User *, user_free);
-bool user_check_gc(User *u, bool drop_not_started);
+bool user_may_gc(User *u, bool drop_not_started);
void user_add_to_gc_queue(User *u);
int user_start(User *u);
int user_stop(User *u, bool force);
diff --git a/src/login/logind.c b/src/login/logind.c
index d15d4cec5b..5220861c1d 100644
--- a/src/login/logind.c
+++ b/src/login/logind.c
@@ -35,6 +35,7 @@
#include "dirent-util.h"
#include "fd-util.h"
#include "format-util.h"
+#include "fs-util.h"
#include "logind.h"
#include "process-util.h"
#include "selinux-util.h"
@@ -53,6 +54,7 @@ static void manager_reset_config(Manager *m) {
m->handle_suspend_key = HANDLE_SUSPEND;
m->handle_hibernate_key = HANDLE_HIBERNATE;
m->handle_lid_switch = HANDLE_SUSPEND;
+ m->handle_lid_switch_ep = _HANDLE_ACTION_INVALID;
m->handle_lid_switch_docked = HANDLE_IGNORE;
m->power_key_ignore_inhibited = false;
m->suspend_key_ignore_inhibited = false;
@@ -182,7 +184,7 @@ static void manager_free(Manager *m) {
udev_unref(m->udev);
if (m->unlink_nologin)
- (void) unlink("/run/nologin");
+ (void) unlink_or_warn("/run/nologin");
bus_verify_polkit_async_registry_free(m->polkit_registry);
@@ -253,11 +255,7 @@ static int manager_enumerate_buttons(Manager *m) {
/* Loads buttons from udev */
- if (m->handle_power_key == HANDLE_IGNORE &&
- m->handle_suspend_key == HANDLE_IGNORE &&
- m->handle_hibernate_key == HANDLE_IGNORE &&
- m->handle_lid_switch == HANDLE_IGNORE &&
- m->handle_lid_switch_docked == HANDLE_IGNORE)
+ if (manager_all_buttons_ignored(m))
return 0;
e = udev_enumerate_new(m->udev);
@@ -325,7 +323,9 @@ static int manager_enumerate_seats(Manager *m) {
s = hashmap_get(m->seats, de->d_name);
if (!s) {
- unlinkat(dirfd(d), de->d_name, 0);
+ if (unlinkat(dirfd(d), de->d_name, 0) < 0)
+ log_warning("Failed to remove /run/systemd/seats/%s: %m",
+ de->d_name);
continue;
}
@@ -453,9 +453,15 @@ static int manager_attach_fds(Manager *m) {
continue;
}
+ if (!S_ISCHR(st.st_mode) && !S_ISBLK(st.st_mode)) {
+ log_debug("Device fd doesn't actually point to device node: %m");
+ close_nointr(fd);
+ continue;
+ }
+
sd = hashmap_get(s->devices, &st.st_rdev);
if (!sd) {
- /* Weird we got an fd for a session device which wasn't
+ /* Weird, we got an fd for a session device which wasn't
* recorded in the session state file... */
log_warning("Got fd for missing session device [%u:%u] in session %s",
major(st.st_rdev), minor(st.st_rdev), s->id);
@@ -905,12 +911,7 @@ static int manager_connect_udev(Manager *m) {
return r;
/* Don't watch keys if nobody cares */
- if (m->handle_power_key != HANDLE_IGNORE ||
- m->handle_suspend_key != HANDLE_IGNORE ||
- m->handle_hibernate_key != HANDLE_IGNORE ||
- m->handle_lid_switch != HANDLE_IGNORE ||
- m->handle_lid_switch_docked != HANDLE_IGNORE) {
-
+ if (!manager_all_buttons_ignored(m)) {
m->udev_button_monitor = udev_monitor_new_from_netlink(m->udev, "udev");
if (!m->udev_button_monitor)
return -ENOMEM;
@@ -966,7 +967,7 @@ static void manager_gc(Manager *m, bool drop_not_started) {
LIST_REMOVE(gc_queue, m->seat_gc_queue, seat);
seat->in_gc_queue = false;
- if (!seat_check_gc(seat, drop_not_started)) {
+ if (seat_may_gc(seat, drop_not_started)) {
seat_stop(seat, false);
seat_free(seat);
}
@@ -977,14 +978,14 @@ static void manager_gc(Manager *m, bool drop_not_started) {
session->in_gc_queue = false;
/* First, if we are not closing yet, initiate stopping */
- if (!session_check_gc(session, drop_not_started) &&
+ if (session_may_gc(session, drop_not_started) &&
session_get_state(session) != SESSION_CLOSING)
session_stop(session, false);
/* Normally, this should make the session referenced
* again, if it doesn't then let's get rid of it
* immediately */
- if (!session_check_gc(session, drop_not_started)) {
+ if (session_may_gc(session, drop_not_started)) {
session_finalize(session);
session_free(session);
}
@@ -995,11 +996,11 @@ static void manager_gc(Manager *m, bool drop_not_started) {
user->in_gc_queue = false;
/* First step: queue stop jobs */
- if (!user_check_gc(user, drop_not_started))
+ if (user_may_gc(user, drop_not_started))
user_stop(user, false);
/* Second step: finalize user */
- if (!user_check_gc(user, drop_not_started)) {
+ if (user_may_gc(user, drop_not_started)) {
user_finalize(user);
user_free(user);
}
diff --git a/src/login/logind.conf.in b/src/login/logind.conf.in
index 6f720b7708..40a77dc7be 100644
--- a/src/login/logind.conf.in
+++ b/src/login/logind.conf.in
@@ -22,6 +22,7 @@
#HandleSuspendKey=suspend
#HandleHibernateKey=hibernate
#HandleLidSwitch=suspend
+#HandleLidSwitchExternalPower=suspend
#HandleLidSwitchDocked=ignore
#PowerKeyIgnoreInhibited=no
#SuspendKeyIgnoreInhibited=no
diff --git a/src/login/logind.h b/src/login/logind.h
index 8262367135..918bc1f919 100644
--- a/src/login/logind.h
+++ b/src/login/logind.h
@@ -118,6 +118,7 @@ struct Manager {
HandleAction handle_suspend_key;
HandleAction handle_hibernate_key;
HandleAction handle_lid_switch;
+ HandleAction handle_lid_switch_ep;
HandleAction handle_lid_switch_docked;
bool power_key_ignore_inhibited;
@@ -160,6 +161,8 @@ int manager_get_user_by_pid(Manager *m, pid_t pid, User **user);
int manager_get_session_by_pid(Manager *m, pid_t pid, Session **session);
bool manager_is_docked_or_external_displays(Manager *m);
+bool manager_is_on_external_power(void);
+bool manager_all_buttons_ignored(Manager *m);
extern const sd_bus_vtable manager_vtable[];
diff --git a/src/login/meson.build b/src/login/meson.build
index e8e4f7bd7d..5b75382e5f 100644
--- a/src/login/meson.build
+++ b/src/login/meson.build
@@ -87,15 +87,8 @@ if conf.get('ENABLE_LOGIND') == 1
install_dir : dbuspolicydir)
install_data('org.freedesktop.login1.service',
install_dir : dbussystemservicedir)
-
- i18n.merge_file(
- 'org.freedesktop.login1.policy',
- input : 'org.freedesktop.login1.policy.in',
- output : 'org.freedesktop.login1.policy',
- po_dir : po_dir,
- data_dirs : po_dir,
- install : install_polkit,
- install_dir : polkitpolicydir)
+ install_data('org.freedesktop.login1.policy',
+ install_dir : polkitpolicydir)
install_data('70-power-switch.rules', install_dir : udevrulesdir)
diff --git a/src/login/org.freedesktop.login1.policy.in b/src/login/org.freedesktop.login1.policy
index 47162022d2..f1d1f956d3 100644
--- a/src/login/org.freedesktop.login1.policy.in
+++ b/src/login/org.freedesktop.login1.policy
@@ -19,8 +19,8 @@
<vendor_url>http://www.freedesktop.org/wiki/Software/systemd</vendor_url>
<action id="org.freedesktop.login1.inhibit-block-shutdown">
- <description>Allow applications to inhibit system shutdown</description>
- <message>Authentication is required for an application to inhibit system shutdown.</message>
+ <description gettext-domain="systemd">Allow applications to inhibit system shutdown</description>
+ <message gettext-domain="systemd">Authentication is required for an application to inhibit system shutdown.</message>
<defaults>
<allow_any>no</allow_any>
<allow_inactive>yes</allow_inactive>
@@ -30,8 +30,8 @@
</action>
<action id="org.freedesktop.login1.inhibit-delay-shutdown">
- <description>Allow applications to delay system shutdown</description>
- <message>Authentication is required for an application to delay system shutdown.</message>
+ <description gettext-domain="systemd">Allow applications to delay system shutdown</description>
+ <message gettext-domain="systemd">Authentication is required for an application to delay system shutdown.</message>
<defaults>
<allow_any>yes</allow_any>
<allow_inactive>yes</allow_inactive>
@@ -41,8 +41,8 @@
</action>
<action id="org.freedesktop.login1.inhibit-block-sleep">
- <description>Allow applications to inhibit system sleep</description>
- <message>Authentication is required for an application to inhibit system sleep.</message>
+ <description gettext-domain="systemd">Allow applications to inhibit system sleep</description>
+ <message gettext-domain="systemd">Authentication is required for an application to inhibit system sleep.</message>
<defaults>
<allow_any>no</allow_any>
<allow_inactive>yes</allow_inactive>
@@ -52,8 +52,8 @@
</action>
<action id="org.freedesktop.login1.inhibit-delay-sleep">
- <description>Allow applications to delay system sleep</description>
- <message>Authentication is required for an application to delay system sleep.</message>
+ <description gettext-domain="systemd">Allow applications to delay system sleep</description>
+ <message gettext-domain="systemd">Authentication is required for an application to delay system sleep.</message>
<defaults>
<allow_any>yes</allow_any>
<allow_inactive>yes</allow_inactive>
@@ -62,8 +62,8 @@
</action>
<action id="org.freedesktop.login1.inhibit-block-idle">
- <description>Allow applications to inhibit automatic system suspend</description>
- <message>Authentication is required for an application to inhibit automatic system suspend.</message>
+ <description gettext-domain="systemd">Allow applications to inhibit automatic system suspend</description>
+ <message gettext-domain="systemd">Authentication is required for an application to inhibit automatic system suspend.</message>
<defaults>
<allow_any>yes</allow_any>
<allow_inactive>yes</allow_inactive>
@@ -72,8 +72,8 @@
</action>
<action id="org.freedesktop.login1.inhibit-handle-power-key">
- <description>Allow applications to inhibit system handling of the power key</description>
- <message>Authentication is required for an application to inhibit system handling of the power key.</message>
+ <description gettext-domain="systemd">Allow applications to inhibit system handling of the power key</description>
+ <message gettext-domain="systemd">Authentication is required for an application to inhibit system handling of the power key.</message>
<defaults>
<allow_any>no</allow_any>
<allow_inactive>yes</allow_inactive>
@@ -83,8 +83,8 @@
</action>
<action id="org.freedesktop.login1.inhibit-handle-suspend-key">
- <description>Allow applications to inhibit system handling of the suspend key</description>
- <message>Authentication is required for an application to inhibit system handling of the suspend key.</message>
+ <description gettext-domain="systemd">Allow applications to inhibit system handling of the suspend key</description>
+ <message gettext-domain="systemd">Authentication is required for an application to inhibit system handling of the suspend key.</message>
<defaults>
<allow_any>no</allow_any>
<allow_inactive>yes</allow_inactive>
@@ -94,8 +94,8 @@
</action>
<action id="org.freedesktop.login1.inhibit-handle-hibernate-key">
- <description>Allow applications to inhibit system handling of the hibernate key</description>
- <message>Authentication is required for an application to inhibit system handling of the hibernate key.</message>
+ <description gettext-domain="systemd">Allow applications to inhibit system handling of the hibernate key</description>
+ <message gettext-domain="systemd">Authentication is required for an application to inhibit system handling of the hibernate key.</message>
<defaults>
<allow_any>no</allow_any>
<allow_inactive>yes</allow_inactive>
@@ -104,8 +104,8 @@
</action>
<action id="org.freedesktop.login1.inhibit-handle-lid-switch">
- <description>Allow applications to inhibit system handling of the lid switch</description>
- <message>Authentication is required for an application to inhibit system handling of the lid switch.</message>
+ <description gettext-domain="systemd">Allow applications to inhibit system handling of the lid switch</description>
+ <message gettext-domain="systemd">Authentication is required for an application to inhibit system handling of the lid switch.</message>
<defaults>
<allow_any>no</allow_any>
<allow_inactive>yes</allow_inactive>
@@ -114,8 +114,8 @@
</action>
<action id="org.freedesktop.login1.set-self-linger">
- <description>Allow non-logged-in user to run programs</description>
- <message>Explicit request is required to run programs as a non-logged-in user.</message>
+ <description gettext-domain="systemd">Allow non-logged-in user to run programs</description>
+ <message gettext-domain="systemd">Explicit request is required to run programs as a non-logged-in user.</message>
<defaults>
<allow_any>yes</allow_any>
<allow_inactive>yes</allow_inactive>
@@ -124,8 +124,8 @@
</action>
<action id="org.freedesktop.login1.set-user-linger">
- <description>Allow non-logged-in users to run programs</description>
- <message>Authentication is required to run programs as a non-logged-in user.</message>
+ <description gettext-domain="systemd">Allow non-logged-in users to run programs</description>
+ <message gettext-domain="systemd">Authentication is required to run programs as a non-logged-in user.</message>
<defaults>
<allow_any>auth_admin_keep</allow_any>
<allow_inactive>auth_admin_keep</allow_inactive>
@@ -134,8 +134,8 @@
</action>
<action id="org.freedesktop.login1.attach-device">
- <description>Allow attaching devices to seats</description>
- <message>Authentication is required for attaching a device to a seat.</message>
+ <description gettext-domain="systemd">Allow attaching devices to seats</description>
+ <message gettext-domain="systemd">Authentication is required for attaching a device to a seat.</message>
<defaults>
<allow_any>auth_admin_keep</allow_any>
<allow_inactive>auth_admin_keep</allow_inactive>
@@ -145,8 +145,8 @@
</action>
<action id="org.freedesktop.login1.flush-devices">
- <description>Flush device to seat attachments</description>
- <message>Authentication is required for resetting how devices are attached to seats.</message>
+ <description gettext-domain="systemd">Flush device to seat attachments</description>
+ <message gettext-domain="systemd">Authentication is required for resetting how devices are attached to seats.</message>
<defaults>
<allow_any>auth_admin_keep</allow_any>
<allow_inactive>auth_admin_keep</allow_inactive>
@@ -155,8 +155,8 @@
</action>
<action id="org.freedesktop.login1.power-off">
- <description>Power off the system</description>
- <message>Authentication is required for powering off the system.</message>
+ <description gettext-domain="systemd">Power off the system</description>
+ <message gettext-domain="systemd">Authentication is required for powering off the system.</message>
<defaults>
<allow_any>auth_admin_keep</allow_any>
<allow_inactive>auth_admin_keep</allow_inactive>
@@ -166,8 +166,8 @@
</action>
<action id="org.freedesktop.login1.power-off-multiple-sessions">
- <description>Power off the system while other users are logged in</description>
- <message>Authentication is required for powering off the system while other users are logged in.</message>
+ <description gettext-domain="systemd">Power off the system while other users are logged in</description>
+ <message gettext-domain="systemd">Authentication is required for powering off the system while other users are logged in.</message>
<defaults>
<allow_any>auth_admin_keep</allow_any>
<allow_inactive>auth_admin_keep</allow_inactive>
@@ -177,8 +177,8 @@
</action>
<action id="org.freedesktop.login1.power-off-ignore-inhibit">
- <description>Power off the system while an application asked to inhibit it</description>
- <message>Authentication is required for powering off the system while an application asked to inhibit it.</message>
+ <description gettext-domain="systemd">Power off the system while an application asked to inhibit it</description>
+ <message gettext-domain="systemd">Authentication is required for powering off the system while an application asked to inhibit it.</message>
<defaults>
<allow_any>auth_admin_keep</allow_any>
<allow_inactive>auth_admin_keep</allow_inactive>
@@ -188,8 +188,8 @@
</action>
<action id="org.freedesktop.login1.reboot">
- <description>Reboot the system</description>
- <message>Authentication is required for rebooting the system.</message>
+ <description gettext-domain="systemd">Reboot the system</description>
+ <message gettext-domain="systemd">Authentication is required for rebooting the system.</message>
<defaults>
<allow_any>auth_admin_keep</allow_any>
<allow_inactive>auth_admin_keep</allow_inactive>
@@ -199,8 +199,8 @@
</action>
<action id="org.freedesktop.login1.reboot-multiple-sessions">
- <description>Reboot the system while other users are logged in</description>
- <message>Authentication is required for rebooting the system while other users are logged in.</message>
+ <description gettext-domain="systemd">Reboot the system while other users are logged in</description>
+ <message gettext-domain="systemd">Authentication is required for rebooting the system while other users are logged in.</message>
<defaults>
<allow_any>auth_admin_keep</allow_any>
<allow_inactive>auth_admin_keep</allow_inactive>
@@ -210,8 +210,8 @@
</action>
<action id="org.freedesktop.login1.reboot-ignore-inhibit">
- <description>Reboot the system while an application asked to inhibit it</description>
- <message>Authentication is required for rebooting the system while an application asked to inhibit it.</message>
+ <description gettext-domain="systemd">Reboot the system while an application asked to inhibit it</description>
+ <message gettext-domain="systemd">Authentication is required for rebooting the system while an application asked to inhibit it.</message>
<defaults>
<allow_any>auth_admin_keep</allow_any>
<allow_inactive>auth_admin_keep</allow_inactive>
@@ -221,8 +221,8 @@
</action>
<action id="org.freedesktop.login1.halt">
- <description>Halt the system</description>
- <message>Authentication is required for halting the system.</message>
+ <description gettext-domain="systemd">Halt the system</description>
+ <message gettext-domain="systemd">Authentication is required for halting the system.</message>
<defaults>
<allow_any>auth_admin_keep</allow_any>
<allow_inactive>auth_admin_keep</allow_inactive>
@@ -232,8 +232,8 @@
</action>
<action id="org.freedesktop.login1.halt-multiple-sessions">
- <description>Halt the system while other users are logged in</description>
- <message>Authentication is required for halting the system while other users are logged in.</message>
+ <description gettext-domain="systemd">Halt the system while other users are logged in</description>
+ <message gettext-domain="systemd">Authentication is required for halting the system while other users are logged in.</message>
<defaults>
<allow_any>auth_admin_keep</allow_any>
<allow_inactive>auth_admin_keep</allow_inactive>
@@ -243,8 +243,8 @@
</action>
<action id="org.freedesktop.login1.halt-ignore-inhibit">
- <description>Halt the system while an application asked to inhibit it</description>
- <message>Authentication is required for halting the system while an application asked to inhibit it.</message>
+ <description gettext-domain="systemd">Halt the system while an application asked to inhibit it</description>
+ <message gettext-domain="systemd">Authentication is required for halting the system while an application asked to inhibit it.</message>
<defaults>
<allow_any>auth_admin_keep</allow_any>
<allow_inactive>auth_admin_keep</allow_inactive>
@@ -254,8 +254,8 @@
</action>
<action id="org.freedesktop.login1.suspend">
- <description>Suspend the system</description>
- <message>Authentication is required for suspending the system.</message>
+ <description gettext-domain="systemd">Suspend the system</description>
+ <message gettext-domain="systemd">Authentication is required for suspending the system.</message>
<defaults>
<allow_any>auth_admin_keep</allow_any>
<allow_inactive>auth_admin_keep</allow_inactive>
@@ -264,8 +264,8 @@
</action>
<action id="org.freedesktop.login1.suspend-multiple-sessions">
- <description>Suspend the system while other users are logged in</description>
- <message>Authentication is required for suspending the system while other users are logged in.</message>
+ <description gettext-domain="systemd">Suspend the system while other users are logged in</description>
+ <message gettext-domain="systemd">Authentication is required for suspending the system while other users are logged in.</message>
<defaults>
<allow_any>auth_admin_keep</allow_any>
<allow_inactive>auth_admin_keep</allow_inactive>
@@ -275,8 +275,8 @@
</action>
<action id="org.freedesktop.login1.suspend-ignore-inhibit">
- <description>Suspend the system while an application asked to inhibit it</description>
- <message>Authentication is required for suspending the system while an application asked to inhibit it.</message>
+ <description gettext-domain="systemd">Suspend the system while an application asked to inhibit it</description>
+ <message gettext-domain="systemd">Authentication is required for suspending the system while an application asked to inhibit it.</message>
<defaults>
<allow_any>auth_admin_keep</allow_any>
<allow_inactive>auth_admin_keep</allow_inactive>
@@ -286,8 +286,8 @@
</action>
<action id="org.freedesktop.login1.hibernate">
- <description>Hibernate the system</description>
- <message>Authentication is required for hibernating the system.</message>
+ <description gettext-domain="systemd">Hibernate the system</description>
+ <message gettext-domain="systemd">Authentication is required for hibernating the system.</message>
<defaults>
<allow_any>auth_admin_keep</allow_any>
<allow_inactive>auth_admin_keep</allow_inactive>
@@ -296,8 +296,8 @@
</action>
<action id="org.freedesktop.login1.hibernate-multiple-sessions">
- <description>Hibernate the system while other users are logged in</description>
- <message>Authentication is required for hibernating the system while other users are logged in.</message>
+ <description gettext-domain="systemd">Hibernate the system while other users are logged in</description>
+ <message gettext-domain="systemd">Authentication is required for hibernating the system while other users are logged in.</message>
<defaults>
<allow_any>auth_admin_keep</allow_any>
<allow_inactive>auth_admin_keep</allow_inactive>
@@ -307,8 +307,8 @@
</action>
<action id="org.freedesktop.login1.hibernate-ignore-inhibit">
- <description>Hibernate the system while an application asked to inhibit it</description>
- <message>Authentication is required for hibernating the system while an application asked to inhibit it.</message>
+ <description gettext-domain="systemd">Hibernate the system while an application asked to inhibit it</description>
+ <message gettext-domain="systemd">Authentication is required for hibernating the system while an application asked to inhibit it.</message>
<defaults>
<allow_any>auth_admin_keep</allow_any>
<allow_inactive>auth_admin_keep</allow_inactive>
@@ -318,8 +318,8 @@
</action>
<action id="org.freedesktop.login1.manage">
- <description>Manage active sessions, users and seats</description>
- <message>Authentication is required for managing active sessions, users and seats.</message>
+ <description gettext-domain="systemd">Manage active sessions, users and seats</description>
+ <message gettext-domain="systemd">Authentication is required for managing active sessions, users and seats.</message>
<defaults>
<allow_any>auth_admin_keep</allow_any>
<allow_inactive>auth_admin_keep</allow_inactive>
@@ -328,8 +328,8 @@
</action>
<action id="org.freedesktop.login1.lock-sessions">
- <description>Lock or unlock active sessions</description>
- <message>Authentication is required to lock or unlock active sessions.</message>
+ <description gettext-domain="systemd">Lock or unlock active sessions</description>
+ <message gettext-domain="systemd">Authentication is required to lock or unlock active sessions.</message>
<defaults>
<allow_any>auth_admin_keep</allow_any>
<allow_inactive>auth_admin_keep</allow_inactive>
@@ -338,8 +338,8 @@
</action>
<action id="org.freedesktop.login1.set-reboot-to-firmware-setup">
- <description>Allow indication to the firmware to boot to setup interface</description>
- <message>Authentication is required to indicate to the firmware to boot to setup interface.</message>
+ <description gettext-domain="systemd">Allow indication to the firmware to boot to setup interface</description>
+ <message gettext-domain="systemd">Authentication is required to indicate to the firmware to boot to setup interface.</message>
<defaults>
<allow_any>auth_admin_keep</allow_any>
<allow_inactive>auth_admin_keep</allow_inactive>
@@ -348,8 +348,8 @@
</action>
<action id="org.freedesktop.login1.set-wall-message">
- <description>Set a wall message</description>
- <message>Authentication is required to set a wall message</message>
+ <description gettext-domain="systemd">Set a wall message</description>
+ <message gettext-domain="systemd">Authentication is required to set a wall message</message>
<defaults>
<allow_any>auth_admin_keep</allow_any>
<allow_inactive>auth_admin_keep</allow_inactive>