m->n_autovts = 6;
m->inhibit_delay_max = 5 * USEC_PER_SEC;
- m->handle_power_key = HANDLE_YES;
- m->handle_sleep_key = HANDLE_YES;
- m->handle_lid_switch = HANDLE_NO;
+ m->handle_power_key = HANDLE_NO_SESSION;
+ m->handle_sleep_key = HANDLE_TTY_SESSION;
+ m->handle_lid_switch = HANDLE_OFF;
m->devices = hashmap_new(string_hash_func, string_compare_func);
m->seats = hashmap_new(string_hash_func, string_compare_func);
m->inhibitors = hashmap_new(string_hash_func, string_compare_func);
m->buttons = hashmap_new(string_hash_func, string_compare_func);
- m->cgroups = hashmap_new(string_hash_func, string_compare_func);
+ m->user_cgroups = hashmap_new(string_hash_func, string_compare_func);
+ m->session_cgroups = hashmap_new(string_hash_func, string_compare_func);
+
m->session_fds = hashmap_new(trivial_hash_func, trivial_compare_func);
m->inhibitor_fds = hashmap_new(trivial_hash_func, trivial_compare_func);
m->button_fds = hashmap_new(trivial_hash_func, trivial_compare_func);
if (!m->devices || !m->seats || !m->sessions || !m->users || !m->inhibitors || !m->buttons ||
- !m->cgroups || !m->session_fds || !m->inhibitor_fds || !m->button_fds) {
+ !m->user_cgroups || !m->session_cgroups ||
+ !m->session_fds || !m->inhibitor_fds || !m->button_fds) {
manager_free(m);
return NULL;
}
hashmap_free(m->inhibitors);
hashmap_free(m->buttons);
- hashmap_free(m->cgroups);
+ hashmap_free(m->user_cgroups);
+ hashmap_free(m->session_cgroups);
+
hashmap_free(m->session_fds);
hashmap_free(m->inhibitor_fds);
hashmap_free(m->button_fds);
assert(m);
assert(name);
- r = get_user_creds(&name, &uid, &gid, NULL);
+ r = get_user_creds(&name, &uid, &gid, NULL, NULL);
if (r < 0)
return r;
/* Loads buttons from udev */
+ if (m->handle_power_key == HANDLE_OFF &&
+ m->handle_sleep_key == HANDLE_OFF &&
+ m->handle_lid_switch == HANDLE_OFF)
+ return 0;
+
e = udev_enumerate_new(m->udev);
if (!e) {
r = -ENOMEM;
assert(cgroup);
assert(session);
- s = hashmap_get(m->cgroups, cgroup);
+ s = hashmap_get(m->session_cgroups, cgroup);
if (s) {
*session = s;
return 1;
}
p = strdup(cgroup);
- if (!p) {
- log_error("Out of memory.");
- return -ENOMEM;
- }
+ if (!p)
+ return log_oom();
for (;;) {
char *e;
*e = 0;
- s = hashmap_get(m->cgroups, p);
+ s = hashmap_get(m->session_cgroups, p);
if (s) {
free(p);
*session = s;
}
}
+int manager_get_user_by_cgroup(Manager *m, const char *cgroup, User **user) {
+ User *u;
+ char *p;
+
+ assert(m);
+ assert(cgroup);
+ assert(user);
+
+ u = hashmap_get(m->user_cgroups, cgroup);
+ if (u) {
+ *user = u;
+ return 1;
+ }
+
+ p = strdup(cgroup);
+ if (!p)
+ return log_oom();
+
+ for (;;) {
+ char *e;
+
+ e = strrchr(p, '/');
+ if (!e || e == p) {
+ free(p);
+ *user = NULL;
+ return 0;
+ }
+
+ *e = 0;
+
+ u = hashmap_get(m->user_cgroups, p);
+ if (u) {
+ free(p);
+ *user = u;
+ return 1;
+ }
+ }
+}
+
int manager_get_session_by_pid(Manager *m, pid_t pid, Session **session) {
char *p;
int r;
void manager_cgroup_notify_empty(Manager *m, const char *cgroup) {
Session *s;
+ User *u;
int r;
r = manager_get_session_by_cgroup(m, cgroup, &s);
- if (r <= 0)
- return;
+ if (r > 0)
+ session_add_to_gc_queue(s);
- session_add_to_gc_queue(s);
+ r = manager_get_user_by_cgroup(m, cgroup, &u);
+ if (r > 0)
+ user_add_to_gc_queue(u);
}
static void manager_dispatch_other(Manager *m, int fd) {
!dbus_connection_register_fallback(m->bus, "/org/freedesktop/login1/session", &bus_session_vtable, m) ||
!dbus_connection_register_fallback(m->bus, "/org/freedesktop/login1/user", &bus_user_vtable, m) ||
!dbus_connection_add_filter(m->bus, bus_message_filter, m, NULL)) {
- log_error("Not enough memory");
- r = -ENOMEM;
+ r = log_oom();
goto fail;
}
m->console_active_fd = open("/sys/class/tty/tty0/active", O_RDONLY|O_NOCTTY|O_CLOEXEC);
if (m->console_active_fd < 0) {
+
+ /* On some systems the device node /dev/tty0 may exist
+ * even though /sys/class/tty/tty0 does not. */
+ if (errno == ENOENT)
+ return 0;
+
log_error("Failed to open /sys/class/tty/tty0/active: %m");
return -errno;
}
zero(ev);
ev.events = EPOLLIN;
ev.data.u32 = FD_SEAT_UDEV;
-
if (epoll_ctl(m->epoll_fd, EPOLL_CTL_ADD, m->udev_seat_fd, &ev) < 0)
return -errno;
- m->udev_button_monitor = udev_monitor_new_from_netlink(m->udev, "udev");
- if (!m->udev_button_monitor)
- return -ENOMEM;
+ /* Don't watch keys if nobody cares */
+ if (m->handle_power_key != HANDLE_OFF ||
+ m->handle_sleep_key != HANDLE_OFF ||
+ m->handle_lid_switch != HANDLE_OFF) {
- r = udev_monitor_filter_add_match_tag(m->udev_button_monitor, "power-switch");
- if (r < 0)
- return r;
+ m->udev_button_monitor = udev_monitor_new_from_netlink(m->udev, "udev");
+ if (!m->udev_button_monitor)
+ return -ENOMEM;
- r = udev_monitor_filter_add_match_subsystem_devtype(m->udev_button_monitor, "input", NULL);
- if (r < 0)
- return r;
+ r = udev_monitor_filter_add_match_tag(m->udev_button_monitor, "power-switch");
+ if (r < 0)
+ return r;
- r = udev_monitor_enable_receiving(m->udev_button_monitor);
- if (r < 0)
- return r;
+ r = udev_monitor_filter_add_match_subsystem_devtype(m->udev_button_monitor, "input", NULL);
+ if (r < 0)
+ return r;
- m->udev_button_fd = udev_monitor_get_fd(m->udev_button_monitor);
+ r = udev_monitor_enable_receiving(m->udev_button_monitor);
+ if (r < 0)
+ return r;
- zero(ev);
- ev.events = EPOLLIN;
- ev.data.u32 = FD_BUTTON_UDEV;
+ m->udev_button_fd = udev_monitor_get_fd(m->udev_button_monitor);
- if (epoll_ctl(m->epoll_fd, EPOLL_CTL_ADD, m->udev_button_fd, &ev) < 0)
- return -errno;
+ zero(ev);
+ ev.events = EPOLLIN;
+ ev.data.u32 = FD_BUTTON_UDEV;
+ if (epoll_ctl(m->epoll_fd, EPOLL_CTL_ADD, m->udev_button_fd, &ev) < 0)
+ return -errno;
+ }
/* Don't bother watching VCSA devices, if nobody cares */
- if (m->n_autovts <= 0 || m->console_active_fd < 0)
- return 0;
-
- m->udev_vcsa_monitor = udev_monitor_new_from_netlink(m->udev, "udev");
- if (!m->udev_vcsa_monitor)
- return -ENOMEM;
+ if (m->n_autovts > 0 && m->console_active_fd >= 0) {
- r = udev_monitor_filter_add_match_subsystem_devtype(m->udev_vcsa_monitor, "vc", NULL);
- if (r < 0)
- return r;
+ m->udev_vcsa_monitor = udev_monitor_new_from_netlink(m->udev, "udev");
+ if (!m->udev_vcsa_monitor)
+ return -ENOMEM;
- r = udev_monitor_enable_receiving(m->udev_vcsa_monitor);
- if (r < 0)
- return r;
+ r = udev_monitor_filter_add_match_subsystem_devtype(m->udev_vcsa_monitor, "vc", NULL);
+ if (r < 0)
+ return r;
- m->udev_vcsa_fd = udev_monitor_get_fd(m->udev_vcsa_monitor);
+ r = udev_monitor_enable_receiving(m->udev_vcsa_monitor);
+ if (r < 0)
+ return r;
- zero(ev);
- ev.events = EPOLLIN;
- ev.data.u32 = FD_VCSA_UDEV;
+ m->udev_vcsa_fd = udev_monitor_get_fd(m->udev_vcsa_monitor);
- if (epoll_ctl(m->epoll_fd, EPOLL_CTL_ADD, m->udev_vcsa_fd, &ev) < 0)
- return -errno;
+ zero(ev);
+ ev.events = EPOLLIN;
+ ev.data.u32 = FD_VCSA_UDEV;
+ if (epoll_ctl(m->epoll_fd, EPOLL_CTL_ADD, m->udev_vcsa_fd, &ev) < 0)
+ return -errno;
+ }
return 0;
}
m = manager_new();
if (!m) {
- log_error("Out of memory");
- r = -ENOMEM;
+ r = log_oom();
goto finish;
}