logind.c revision 718d006a63f773c42106494e823250c48942cf08
7ccbd1ae843d77275f2c542582a9a80e5e058a70Lennart Poettering/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
7ccbd1ae843d77275f2c542582a9a80e5e058a70Lennart Poettering This file is part of systemd.
7ccbd1ae843d77275f2c542582a9a80e5e058a70Lennart Poettering Copyright 2011 Lennart Poettering
7ccbd1ae843d77275f2c542582a9a80e5e058a70Lennart Poettering systemd is free software; you can redistribute it and/or modify it
7ccbd1ae843d77275f2c542582a9a80e5e058a70Lennart Poettering under the terms of the GNU Lesser General Public License as published by
7ccbd1ae843d77275f2c542582a9a80e5e058a70Lennart Poettering the Free Software Foundation; either version 2.1 of the License, or
7ccbd1ae843d77275f2c542582a9a80e5e058a70Lennart Poettering (at your option) any later version.
7ccbd1ae843d77275f2c542582a9a80e5e058a70Lennart Poettering systemd is distributed in the hope that it will be useful, but
7ccbd1ae843d77275f2c542582a9a80e5e058a70Lennart Poettering WITHOUT ANY WARRANTY; without even the implied warranty of
7ccbd1ae843d77275f2c542582a9a80e5e058a70Lennart Poettering MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
7ccbd1ae843d77275f2c542582a9a80e5e058a70Lennart Poettering Lesser General Public License for more details.
7ccbd1ae843d77275f2c542582a9a80e5e058a70Lennart Poettering You should have received a copy of the GNU Lesser General Public License
7ccbd1ae843d77275f2c542582a9a80e5e058a70Lennart Poettering along with systemd; If not, see <http://www.gnu.org/licenses/>.
7ccbd1ae843d77275f2c542582a9a80e5e058a70Lennart Poettering m->handle_hibernate_key = HANDLE_HIBERNATE;
7ccbd1ae843d77275f2c542582a9a80e5e058a70Lennart Poettering m->idle_action_usec = 30 * USEC_PER_MINUTE;
7ccbd1ae843d77275f2c542582a9a80e5e058a70Lennart Poettering m->idle_action_not_before_usec = now(CLOCK_MONOTONIC);
7ccbd1ae843d77275f2c542582a9a80e5e058a70Lennart Poettering m->devices = hashmap_new(string_hash_func, string_compare_func);
7ccbd1ae843d77275f2c542582a9a80e5e058a70Lennart Poettering m->seats = hashmap_new(string_hash_func, string_compare_func);
7ccbd1ae843d77275f2c542582a9a80e5e058a70Lennart Poettering m->sessions = hashmap_new(string_hash_func, string_compare_func);
7ccbd1ae843d77275f2c542582a9a80e5e058a70Lennart Poettering m->users = hashmap_new(trivial_hash_func, trivial_compare_func);
7ccbd1ae843d77275f2c542582a9a80e5e058a70Lennart Poettering m->inhibitors = hashmap_new(string_hash_func, string_compare_func);
7ccbd1ae843d77275f2c542582a9a80e5e058a70Lennart Poettering m->buttons = hashmap_new(string_hash_func, string_compare_func);
7ccbd1ae843d77275f2c542582a9a80e5e058a70Lennart Poettering m->user_units = hashmap_new(string_hash_func, string_compare_func);
7ccbd1ae843d77275f2c542582a9a80e5e058a70Lennart Poettering m->session_units = hashmap_new(string_hash_func, string_compare_func);
7ccbd1ae843d77275f2c542582a9a80e5e058a70Lennart Poettering m->session_fds = hashmap_new(trivial_hash_func, trivial_compare_func);
7ccbd1ae843d77275f2c542582a9a80e5e058a70Lennart Poettering m->inhibitor_fds = hashmap_new(trivial_hash_func, trivial_compare_func);
7ccbd1ae843d77275f2c542582a9a80e5e058a70Lennart Poettering m->button_fds = hashmap_new(trivial_hash_func, trivial_compare_func);
7ccbd1ae843d77275f2c542582a9a80e5e058a70Lennart Poettering if (!m->devices || !m->seats || !m->sessions || !m->users || !m->inhibitors || !m->buttons ||
7ccbd1ae843d77275f2c542582a9a80e5e058a70Lennart Poettering !m->session_fds || !m->inhibitor_fds || !m->button_fds) {
7ccbd1ae843d77275f2c542582a9a80e5e058a70Lennart Poettering m->kill_exclude_users = strv_new("root", NULL);
assert(m);
user_free(u);
device_free(d);
seat_free(s);
inhibitor_free(i);
button_free(b);
if (m->console_active_fd >= 0)
if (m->udev_seat_monitor)
if (m->udev_device_monitor)
if (m->udev_vcsa_monitor)
if (m->udev_button_monitor)
if (m->udev)
if (m->bus) {
if (m->bus_fd >= 0)
if (m->epoll_fd >= 0)
if (m->reserve_vt_fd >= 0)
if (m->idle_action_fd >= 0)
free(m);
Device *d;
assert(m);
if (_device)
*_device = d;
return -ENOMEM;
if (_device)
*_device = d;
Seat *s;
assert(m);
if (_seat)
*_seat = s;
return -ENOMEM;
if (_seat)
*_seat = s;
Session *s;
assert(m);
if (_session)
*_session = s;
return -ENOMEM;
if (_session)
*_session = s;
User *u;
assert(m);
if (_user)
*_user = u;
return -ENOMEM;
if (_user)
*_user = u;
assert(m);
struct passwd *p;
assert(m);
errno = 0;
Inhibitor *i;
assert(m);
if (_inhibitor)
*_inhibitor = i;
return -ENOMEM;
if (_inhibitor)
*_inhibitor = i;
Button *b;
assert(m);
if (_button)
*_button = b;
return -ENOMEM;
if (_button)
*_button = b;
assert(m);
if (!device)
const char *sn;
bool master;
if (!seat) {
Button *b;
assert(m);
button_free(b);
const char *sn;
button_open(b);
struct udev_enumerate *e;
assert(m);
r = -ENOMEM;
goto finish;
goto finish;
r = udev_enumerate_scan_devices(e);
goto finish;
struct udev_device *d;
r = -ENOMEM;
goto finish;
k = manager_process_seat_device(m, d);
struct udev_enumerate *e;
assert(m);
r = -ENOMEM;
goto finish;
goto finish;
goto finish;
r = udev_enumerate_scan_devices(e);
goto finish;
struct udev_device *d;
r = -ENOMEM;
goto finish;
k = manager_process_button_device(m, d);
assert(m);
return -errno;
Seat *s;
k = seat_load(s);
assert(m);
return -errno;
assert(m);
r = manager_enumerate_linger_users(m);
return -errno;
User *u;
k = user_load(u);
assert(m);
return -errno;
struct Session *s;
r = -EINVAL;
k = session_load(s);
assert(m);
return -errno;
Inhibitor *i;
k = inhibitor_load(i);
struct udev_device *d;
assert(m);
return -ENOMEM;
r = manager_process_seat_device(m, d);
struct udev_device *d;
assert(m);
return -ENOMEM;
r = manager_process_seat_device(m, d);
struct udev_device *d;
const char *name;
assert(m);
return -ENOMEM;
struct udev_device *d;
assert(m);
return -ENOMEM;
r = manager_process_button_device(m, d);
assert(m);
if (m->vtconsole)
int r = 0, fd;
if (fd < 0)
return -errno;
r = -errno;
assert(m);
return -EBUSY;
r = -ENOMEM;
goto finish;
m->bus,
"org.freedesktop.systemd1",
"/org/freedesktop/systemd1",
"org.freedesktop.systemd1.Manager",
NULL,
NULL,
assert(m);
if (m->reserve_vt <= 0)
return log_oom();
if (m->reserve_vt_fd < 0) {
return -errno;
Session *s;
assert(m);
*session = s;
User *u;
assert(m);
*user = u;
Session *s;
Inhibitor *i;
Button *b;
assert_se(m);
session_stop(s);
inhibitor_stop(i);
inhibitor_free(i);
button_process(b);
assert(m);
if (!m->bus) {
r = -ECONNREFUSED;
goto fail;
if (!dbus_connection_register_object_path(m->bus, "/org/freedesktop/login1", &bus_manager_vtable, m) ||
!dbus_connection_register_fallback(m->bus, "/org/freedesktop/login1/session", &bus_session_vtable, m) ||
r = log_oom();
goto fail;
"sender='org.freedesktop.systemd1',"
"interface='org.freedesktop.systemd1.Manager',"
"path='/org/freedesktop/systemd1'",
&error);
"sender='org.freedesktop.systemd1',"
"interface='org.freedesktop.systemd1.Manager',"
"path='/org/freedesktop/systemd1'",
&error);
"sender='org.freedesktop.systemd1',"
&error);
"sender='org.freedesktop.systemd1',"
"interface='org.freedesktop.systemd1.Manager',"
"path='/org/freedesktop/systemd1'",
&error);
m->bus,
"org.freedesktop.systemd1",
"/org/freedesktop/systemd1",
"org.freedesktop.systemd1.Manager",
NULL,
&error,
r = -EIO;
goto fail;
if (r != DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER) {
r = -EEXIST;
goto fail;
if (m->bus_fd < 0) {
r = m->bus_fd;
goto fail;
goto fail;
fail:
.events = 0,
assert(m);
if (m->console_active_fd < 0) {
return -errno;
return -errno;
assert(m);
if (!m->udev_seat_monitor)
return -ENOMEM;
return -errno;
if (!m->udev_device_monitor)
return -ENOMEM;
return -errno;
if (!m->udev_button_monitor)
return -ENOMEM;
return -errno;
if (!m->udev_vcsa_monitor)
return -ENOMEM;
return -errno;
assert(m);
Session *s;
bool idle_hint;
Iterator i;
assert(m);
int ih;
if (ih < 0)
return ih;
if (!ih) {
if (!idle_hint) {
ts = k;
idle_hint = false;
ts = k;
} else if (idle_hint) {
ts = k;
*t = ts;
return idle_hint;
assert(m);
if (!m->kill_user_processes)
usec_t n;
assert(m);
m->idle_action_usec <= 0) {
goto finish;
(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;
timespec_store(&its.it_value, MAX(since.monotonic, m->idle_action_not_before_usec) + m->idle_action_usec);
if (m->idle_action_fd < 0) {
if (m->idle_action_fd < 0) {
r = -errno;
goto finish;
r = -errno;
goto finish;
r = -errno;
goto finish;
if (m->idle_action_fd >= 0) {
Iterator i;
assert(m);
if (m->epoll_fd < 0)
return -errno;
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);
Iterator i;
Button *b;
assert(m);
q = button_recheck(b);
assert(m);
manager_gc(m, true);
if (manager_dispatch_delayed(m) > 0)
if (manager_recheck_buttons(m) > 0)
manager_gc(m, true);
usec_t x, y;
return -errno;
case FD_SEAT_UDEV:
case FD_DEVICE_UDEV:
case FD_VCSA_UDEV:
case FD_BUTTON_UDEV:
case FD_CONSOLE:
case FD_IDLE_ACTION:
case FD_BUS:
assert(m);
return -errno;
(void*) logind_gperf_lookup, false, false, 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);