logind.c revision 3c56cab44150ad47323970cfadfb0257c6305a74
5430f7f2bc7330f3088b894166bf3524a067e3d8Lennart Poettering/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
5430f7f2bc7330f3088b894166bf3524a067e3d8Lennart Poettering This file is part of systemd.
5430f7f2bc7330f3088b894166bf3524a067e3d8Lennart Poettering Copyright 2011 Lennart Poettering
5430f7f2bc7330f3088b894166bf3524a067e3d8Lennart Poettering systemd is free software; you can redistribute it and/or modify it
5430f7f2bc7330f3088b894166bf3524a067e3d8Lennart Poettering under the terms of the GNU Lesser General Public License as published by
5430f7f2bc7330f3088b894166bf3524a067e3d8Lennart Poettering the Free Software Foundation; either version 2.1 of the License, or
5430f7f2bc7330f3088b894166bf3524a067e3d8Lennart Poettering (at your option) any later version.
5430f7f2bc7330f3088b894166bf3524a067e3d8Lennart Poettering systemd is distributed in the hope that it will be useful, but
5430f7f2bc7330f3088b894166bf3524a067e3d8Lennart Poettering WITHOUT ANY WARRANTY; without even the implied warranty of
5430f7f2bc7330f3088b894166bf3524a067e3d8Lennart Poettering MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
5430f7f2bc7330f3088b894166bf3524a067e3d8Lennart Poettering Lesser General Public License for more details.
5430f7f2bc7330f3088b894166bf3524a067e3d8Lennart Poettering You should have received a copy of the GNU Lesser General Public License
5430f7f2bc7330f3088b894166bf3524a067e3d8Lennart Poettering along with systemd; If not, see <http://www.gnu.org/licenses/>.
5430f7f2bc7330f3088b894166bf3524a067e3d8Lennart Poettering m->handle_hibernate_key = HANDLE_HIBERNATE;
6126a412dbc7628cbc94660e57bd6915e842c2d4Ramkumar Ramachandra m->handle_lid_switch_docked = HANDLE_IGNORE;
5430f7f2bc7330f3088b894166bf3524a067e3d8Lennart Poettering m->idle_action_usec = 30 * USEC_PER_MINUTE;
5430f7f2bc7330f3088b894166bf3524a067e3d8Lennart Poettering m->idle_action_not_before_usec = now(CLOCK_MONOTONIC);
5430f7f2bc7330f3088b894166bf3524a067e3d8Lennart Poettering m->runtime_dir_size = PAGE_ALIGN((size_t) (physical_memory() / 10)); /* 10% */
5430f7f2bc7330f3088b894166bf3524a067e3d8Lennart Poettering m->devices = hashmap_new(string_hash_func, string_compare_func);
5430f7f2bc7330f3088b894166bf3524a067e3d8Lennart Poettering m->seats = hashmap_new(string_hash_func, string_compare_func);
5430f7f2bc7330f3088b894166bf3524a067e3d8Lennart Poettering m->sessions = hashmap_new(string_hash_func, string_compare_func);
5430f7f2bc7330f3088b894166bf3524a067e3d8Lennart Poettering m->users = hashmap_new(trivial_hash_func, trivial_compare_func);
5430f7f2bc7330f3088b894166bf3524a067e3d8Lennart Poettering m->inhibitors = hashmap_new(string_hash_func, string_compare_func);
5430f7f2bc7330f3088b894166bf3524a067e3d8Lennart Poettering m->buttons = hashmap_new(string_hash_func, string_compare_func);
5430f7f2bc7330f3088b894166bf3524a067e3d8Lennart Poettering m->user_units = hashmap_new(string_hash_func, string_compare_func);
5430f7f2bc7330f3088b894166bf3524a067e3d8Lennart Poettering m->session_units = hashmap_new(string_hash_func, string_compare_func);
5430f7f2bc7330f3088b894166bf3524a067e3d8Lennart Poettering m->busnames = set_new(string_hash_func, string_compare_func);
5430f7f2bc7330f3088b894166bf3524a067e3d8Lennart Poettering if (!m->devices || !m->seats || !m->sessions || !m->users || !m->inhibitors || !m->buttons || !m->busnames ||
5430f7f2bc7330f3088b894166bf3524a067e3d8Lennart Poettering m->kill_exclude_users = strv_new("root", NULL);
6126a412dbc7628cbc94660e57bd6915e842c2d4Ramkumar Ramachandra while ((session = hashmap_first(m->sessions)))
5430f7f2bc7330f3088b894166bf3524a067e3d8Lennart Poettering while ((i = hashmap_first(m->inhibitors)))
5430f7f2bc7330f3088b894166bf3524a067e3d8Lennart Poettering sd_event_source_unref(m->idle_action_event_source);
5430f7f2bc7330f3088b894166bf3524a067e3d8Lennart Poettering sd_event_source_unref(m->console_active_event_source);
5430f7f2bc7330f3088b894166bf3524a067e3d8Lennart Poettering sd_event_source_unref(m->udev_seat_event_source);
5430f7f2bc7330f3088b894166bf3524a067e3d8Lennart Poettering sd_event_source_unref(m->udev_device_event_source);
5430f7f2bc7330f3088b894166bf3524a067e3d8Lennart Poettering sd_event_source_unref(m->udev_vcsa_event_source);
5430f7f2bc7330f3088b894166bf3524a067e3d8Lennart Poettering sd_event_source_unref(m->udev_button_event_source);
5430f7f2bc7330f3088b894166bf3524a067e3d8Lennart Poettering sd_event_source_unref(m->lid_switch_ignore_event_source);
5430f7f2bc7330f3088b894166bf3524a067e3d8Lennart Poettering udev_monitor_unref(m->udev_seat_monitor);
5430f7f2bc7330f3088b894166bf3524a067e3d8Lennart Poettering udev_monitor_unref(m->udev_device_monitor);
5430f7f2bc7330f3088b894166bf3524a067e3d8Lennart Poettering udev_monitor_unref(m->udev_vcsa_monitor);
5430f7f2bc7330f3088b894166bf3524a067e3d8Lennart Poettering udev_monitor_unref(m->udev_button_monitor);
5430f7f2bc7330f3088b894166bf3524a067e3d8Lennart Poettering bus_verify_polkit_async_registry_free(m->polkit_registry);
5430f7f2bc7330f3088b894166bf3524a067e3d8Lennart Poetteringstatic int manager_enumerate_devices(Manager *m) {
5430f7f2bc7330f3088b894166bf3524a067e3d8Lennart Poettering struct udev_list_entry *item = NULL, *first = NULL;
5430f7f2bc7330f3088b894166bf3524a067e3d8Lennart Poettering _cleanup_udev_enumerate_unref_ struct udev_enumerate *e = NULL;
5430f7f2bc7330f3088b894166bf3524a067e3d8Lennart Poettering /* Loads devices from udev and creates seats for them as
5430f7f2bc7330f3088b894166bf3524a067e3d8Lennart Poettering * necessary */
5430f7f2bc7330f3088b894166bf3524a067e3d8Lennart Poettering r = udev_enumerate_add_match_tag(e, "master-of-seat");
5430f7f2bc7330f3088b894166bf3524a067e3d8Lennart Poettering r = udev_enumerate_add_match_is_initialized(e);
5430f7f2bc7330f3088b894166bf3524a067e3d8Lennart Poettering first = udev_enumerate_get_list_entry(e);
5430f7f2bc7330f3088b894166bf3524a067e3d8Lennart Poettering _cleanup_udev_device_unref_ struct udev_device *d = NULL;
5430f7f2bc7330f3088b894166bf3524a067e3d8Lennart Poettering d = udev_device_new_from_syspath(m->udev, udev_list_entry_get_name(item));
5430f7f2bc7330f3088b894166bf3524a067e3d8Lennart Poetteringstatic int manager_enumerate_buttons(Manager *m) {
5430f7f2bc7330f3088b894166bf3524a067e3d8Lennart Poettering _cleanup_udev_enumerate_unref_ struct udev_enumerate *e = NULL;
5430f7f2bc7330f3088b894166bf3524a067e3d8Lennart Poettering struct udev_list_entry *item = NULL, *first = NULL;
5430f7f2bc7330f3088b894166bf3524a067e3d8Lennart Poettering /* Loads buttons from udev */
5430f7f2bc7330f3088b894166bf3524a067e3d8Lennart Poettering if (m->handle_power_key == HANDLE_IGNORE &&
5430f7f2bc7330f3088b894166bf3524a067e3d8Lennart Poettering m->handle_suspend_key == HANDLE_IGNORE &&
5430f7f2bc7330f3088b894166bf3524a067e3d8Lennart Poettering m->handle_hibernate_key == HANDLE_IGNORE &&
5430f7f2bc7330f3088b894166bf3524a067e3d8Lennart Poettering m->handle_lid_switch_docked == HANDLE_IGNORE)
5430f7f2bc7330f3088b894166bf3524a067e3d8Lennart Poettering r = udev_enumerate_add_match_subsystem(e, "input");
5430f7f2bc7330f3088b894166bf3524a067e3d8Lennart Poettering r = udev_enumerate_add_match_tag(e, "power-switch");
5430f7f2bc7330f3088b894166bf3524a067e3d8Lennart Poettering r = udev_enumerate_add_match_is_initialized(e);
5430f7f2bc7330f3088b894166bf3524a067e3d8Lennart Poettering first = udev_enumerate_get_list_entry(e);
5430f7f2bc7330f3088b894166bf3524a067e3d8Lennart Poettering _cleanup_udev_device_unref_ struct udev_device *d = NULL;
5430f7f2bc7330f3088b894166bf3524a067e3d8Lennart Poettering d = udev_device_new_from_syspath(m->udev, udev_list_entry_get_name(item));
5430f7f2bc7330f3088b894166bf3524a067e3d8Lennart Poetteringstatic int manager_enumerate_seats(Manager *m) {
5430f7f2bc7330f3088b894166bf3524a067e3d8Lennart Poettering /* This loads data about seats stored on disk, but does not
5430f7f2bc7330f3088b894166bf3524a067e3d8Lennart Poettering * actually create any seats. Removes data of seats that no
5430f7f2bc7330f3088b894166bf3524a067e3d8Lennart Poettering * longer exist. */
5430f7f2bc7330f3088b894166bf3524a067e3d8Lennart Poettering log_error("Failed to open /run/systemd/seats: %m");
5430f7f2bc7330f3088b894166bf3524a067e3d8Lennart Poetteringstatic int manager_enumerate_linger_users(Manager *m) {
5430f7f2bc7330f3088b894166bf3524a067e3d8Lennart Poettering log_error("Failed to open /var/lib/systemd/linger/: %m");
5430f7f2bc7330f3088b894166bf3524a067e3d8Lennart Poettering k = manager_add_user_by_name(m, de->d_name, NULL);
5430f7f2bc7330f3088b894166bf3524a067e3d8Lennart Poettering log_notice("Couldn't add lingering user %s: %s", de->d_name, strerror(-k));
5430f7f2bc7330f3088b894166bf3524a067e3d8Lennart Poetteringstatic int manager_enumerate_users(Manager *m) {
5430f7f2bc7330f3088b894166bf3524a067e3d8Lennart Poettering /* Add lingering users */
5430f7f2bc7330f3088b894166bf3524a067e3d8Lennart Poettering /* Read in user data stored on disk */
5430f7f2bc7330f3088b894166bf3524a067e3d8Lennart Poettering log_error("Failed to open /run/systemd/users: %m");
5430f7f2bc7330f3088b894166bf3524a067e3d8Lennart Poettering k = manager_add_user_by_name(m, de->d_name, &u);
5430f7f2bc7330f3088b894166bf3524a067e3d8Lennart Poettering log_error("Failed to add user by file name %s: %s", de->d_name, strerror(-k));
5430f7f2bc7330f3088b894166bf3524a067e3d8Lennart Poetteringstatic int manager_enumerate_sessions(Manager *m) {
5430f7f2bc7330f3088b894166bf3524a067e3d8Lennart Poettering /* Read in session data stored on disk */
6126a412dbc7628cbc94660e57bd6915e842c2d4Ramkumar Ramachandra log_error("Failed to open /run/systemd/sessions: %m");
5430f7f2bc7330f3088b894166bf3524a067e3d8Lennart Poettering log_warning("Invalid session file name '%s', ignoring.", de->d_name);
5430f7f2bc7330f3088b894166bf3524a067e3d8Lennart Poettering k = manager_add_session(m, de->d_name, &s);
5430f7f2bc7330f3088b894166bf3524a067e3d8Lennart Poettering log_error("Failed to add session by file name %s: %s", de->d_name, strerror(-k));
5430f7f2bc7330f3088b894166bf3524a067e3d8Lennart Poetteringstatic int manager_enumerate_inhibitors(Manager *m) {
5430f7f2bc7330f3088b894166bf3524a067e3d8Lennart Poettering log_error("Failed to open /run/systemd/inhibit: %m");
6126a412dbc7628cbc94660e57bd6915e842c2d4Ramkumar Ramachandra k = manager_add_inhibitor(m, de->d_name, &i);
5430f7f2bc7330f3088b894166bf3524a067e3d8Lennart Poettering log_notice("Couldn't add inhibitor %s: %s", de->d_name, strerror(-k));
5430f7f2bc7330f3088b894166bf3524a067e3d8Lennart Poetteringstatic int manager_dispatch_seat_udev(sd_event_source *s, int fd, uint32_t revents, void *userdata) {
5430f7f2bc7330f3088b894166bf3524a067e3d8Lennart Poettering _cleanup_udev_device_unref_ struct udev_device *d = NULL;
5430f7f2bc7330f3088b894166bf3524a067e3d8Lennart Poettering d = udev_monitor_receive_device(m->udev_seat_monitor);
6126a412dbc7628cbc94660e57bd6915e842c2d4Ramkumar Ramachandrastatic int manager_dispatch_device_udev(sd_event_source *s, int fd, uint32_t revents, void *userdata) {
5430f7f2bc7330f3088b894166bf3524a067e3d8Lennart Poettering _cleanup_udev_device_unref_ struct udev_device *d = NULL;
5430f7f2bc7330f3088b894166bf3524a067e3d8Lennart Poettering d = udev_monitor_receive_device(m->udev_device_monitor);
manager_process_seat_device(m, d);
static int manager_dispatch_vcsa_udev(sd_event_source *s, int fd, uint32_t revents, void *userdata) {
const char *name;
assert(m);
return -ENOMEM;
static int manager_dispatch_button_udev(sd_event_source *s, int fd, uint32_t revents, void *userdata) {
assert(m);
return -ENOMEM;
assert(m);
assert(m);
if (m->reserve_vt <= 0)
return log_oom();
if (m->reserve_vt_fd < 0) {
return -errno;
assert(m);
r = sd_bus_add_object_vtable(m->bus, NULL, "/org/freedesktop/login1", "org.freedesktop.login1.Manager", manager_vtable, m);
r = sd_bus_add_fallback_vtable(m->bus, NULL, "/org/freedesktop/login1/seat", "org.freedesktop.login1.Seat", seat_vtable, seat_object_find, m);
r = sd_bus_add_node_enumerator(m->bus, NULL, "/org/freedesktop/login1/seat", seat_node_enumerator, m);
r = sd_bus_add_fallback_vtable(m->bus, NULL, "/org/freedesktop/login1/session", "org.freedesktop.login1.Session", session_vtable, session_object_find, m);
r = sd_bus_add_node_enumerator(m->bus, NULL, "/org/freedesktop/login1/session", session_node_enumerator, m);
r = sd_bus_add_fallback_vtable(m->bus, NULL, "/org/freedesktop/login1/user", "org.freedesktop.login1.User", user_vtable, user_object_find, m);
r = sd_bus_add_node_enumerator(m->bus, NULL, "/org/freedesktop/login1/user", user_node_enumerator, m);
NULL,
"path='/org/freedesktop/DBus'",
NULL,
"sender='org.freedesktop.systemd1',"
"interface='org.freedesktop.systemd1.Manager',"
"path='/org/freedesktop/systemd1'",
match_job_removed, m);
NULL,
"sender='org.freedesktop.systemd1',"
"interface='org.freedesktop.systemd1.Manager',"
"path='/org/freedesktop/systemd1'",
match_unit_removed, m);
NULL,
"sender='org.freedesktop.systemd1',"
NULL,
"sender='org.freedesktop.systemd1',"
"interface='org.freedesktop.systemd1.Manager',"
"path='/org/freedesktop/systemd1'",
match_reloading, m);
r = sd_bus_call_method(
m->bus,
"org.freedesktop.systemd1",
"/org/freedesktop/systemd1",
"org.freedesktop.systemd1.Manager",
&error,
assert(m);
if (m->console_active_fd < 0) {
return -errno;
r = sd_event_add_io(m->event, &m->console_active_event_source, m->console_active_fd, 0, manager_dispatch_console, m);
return -EINVAL;
assert(m);
if (!m->udev_seat_monitor)
return -ENOMEM;
r = sd_event_add_io(m->event, &m->udev_seat_event_source, udev_monitor_get_fd(m->udev_seat_monitor), EPOLLIN, manager_dispatch_seat_udev, m);
if (!m->udev_device_monitor)
return -ENOMEM;
r = sd_event_add_io(m->event, &m->udev_device_event_source, udev_monitor_get_fd(m->udev_device_monitor), EPOLLIN, manager_dispatch_device_udev, m);
if (!m->udev_button_monitor)
return -ENOMEM;
r = sd_event_add_io(m->event, &m->udev_button_event_source, udev_monitor_get_fd(m->udev_button_monitor), EPOLLIN, manager_dispatch_button_udev, m);
if (!m->udev_vcsa_monitor)
return -ENOMEM;
r = sd_event_add_io(m->event, &m->udev_vcsa_event_source, udev_monitor_get_fd(m->udev_vcsa_monitor), EPOLLIN, manager_dispatch_vcsa_udev, m);
assert(m);
assert(m);
m->idle_action_usec <= 0)
(m->idle_action_not_before_usec <= 0 || n >= m->idle_action_not_before_usec + m->idle_action_usec)) {
m->idle_action_not_before_usec = n;
if (!m->idle_action_event_source) {
r = sd_event_add_time(
m->event,
Iterator i;
assert(m);
r = manager_connect_console(m);
r = manager_connect_udev(m);
r = manager_connect_bus(m);
r = manager_enumerate_devices(m);
r = manager_enumerate_seats(m);
r = manager_enumerate_users(m);
r = manager_enumerate_sessions(m);
r = manager_enumerate_inhibitors(m);
r = manager_enumerate_buttons(m);
manager_gc(m, false);
assert(m);
if (r == SD_EVENT_FINISHED)
manager_gc(m, true);
if (manager_dispatch_delayed(m) > 0)
usec_t x, y;
us = x >= y ? 0 : y - x;
assert(m);
log_open();
r = -EINVAL;
goto finish;
m = manager_new();
r = log_oom();
goto finish;
r = manager_startup(m);
goto finish;
sd_notify(false,
r = manager_run(m);
sd_notify(false,
manager_free(m);