summaryrefslogtreecommitdiff
path: root/src/login/logind.c
diff options
context:
space:
mode:
authorLennart Poettering <lennart@poettering.net>2012-04-16 16:47:33 +0200
committerLennart Poettering <lennart@poettering.net>2012-04-16 18:59:08 +0200
commitf8e2fb7b14e53f5a4bcfd66d26910af1dee185c6 (patch)
treec8f7ab02b4525466984a7fa23ebedfde090ef168 /src/login/logind.c
parent9156e799a258658cf3f51434708cdb194c13eaa4 (diff)
logind: add shutdown/suspend/idle inhibition framework
Diffstat (limited to 'src/login/logind.c')
-rw-r--r--src/login/logind.c114
1 files changed, 103 insertions, 11 deletions
diff --git a/src/login/logind.c b/src/login/logind.c
index fc08c4bc69..7222e3aaa7 100644
--- a/src/login/logind.c
+++ b/src/login/logind.c
@@ -55,10 +55,14 @@ Manager *manager_new(void) {
m->seats = hashmap_new(string_hash_func, string_compare_func);
m->sessions = hashmap_new(string_hash_func, string_compare_func);
m->users = hashmap_new(trivial_hash_func, trivial_compare_func);
+ m->inhibitors = hashmap_new(string_hash_func, string_compare_func);
+
m->cgroups = hashmap_new(string_hash_func, string_compare_func);
- m->fifo_fds = hashmap_new(trivial_hash_func, trivial_compare_func);
+ m->session_fds = hashmap_new(trivial_hash_func, trivial_compare_func);
+ m->inhibitor_fds = hashmap_new(trivial_hash_func, trivial_compare_func);
- if (!m->devices || !m->seats || !m->sessions || !m->users || !m->cgroups || !m->fifo_fds) {
+ if (!m->devices || !m->seats || !m->sessions || !m->users || !m->inhibitors ||
+ !m->cgroups || !m->session_fds || !m->inhibitor_fds) {
manager_free(m);
return NULL;
}
@@ -89,6 +93,7 @@ void manager_free(Manager *m) {
User *u;
Device *d;
Seat *s;
+ Inhibitor *i;
assert(m);
@@ -104,12 +109,18 @@ void manager_free(Manager *m) {
while ((s = hashmap_first(m->seats)))
seat_free(s);
- hashmap_free(m->sessions);
- hashmap_free(m->users);
+ while ((i = hashmap_first(m->inhibitors)))
+ inhibitor_free(i);
+
hashmap_free(m->devices);
hashmap_free(m->seats);
+ hashmap_free(m->sessions);
+ hashmap_free(m->users);
+ hashmap_free(m->inhibitors);
+
hashmap_free(m->cgroups);
- hashmap_free(m->fifo_fds);
+ hashmap_free(m->session_fds);
+ hashmap_free(m->inhibitor_fds);
if (m->console_active_fd >= 0)
close_nointr_nofail(m->console_active_fd);
@@ -268,6 +279,30 @@ int manager_add_user_by_uid(Manager *m, uid_t uid, User **_user) {
return manager_add_user(m, uid, p->pw_gid, p->pw_name, _user);
}
+int manager_add_inhibitor(Manager *m, const char* id, Inhibitor **_inhibitor) {
+ Inhibitor *i;
+
+ assert(m);
+ assert(id);
+
+ i = hashmap_get(m->inhibitors, id);
+ if (i) {
+ if (_inhibitor)
+ *_inhibitor = i;
+
+ return 0;
+ }
+
+ i = inhibitor_new(m, id);
+ if (!i)
+ return -ENOMEM;
+
+ if (_inhibitor)
+ *_inhibitor = i;
+
+ return 0;
+}
+
int manager_process_seat_device(Manager *m, struct udev_device *d) {
Device *device;
int r;
@@ -412,10 +447,9 @@ int manager_enumerate_seats(Manager *m) {
}
static int manager_enumerate_users_from_cgroup(Manager *m) {
- int r = 0;
+ int r = 0, k;
char *name;
DIR *d;
- int k;
r = cg_enumerate_subgroups(SYSTEMD_CGROUP_CONTROLLER, m->cgroup_path, &d);
if (r < 0) {
@@ -641,6 +675,46 @@ int manager_enumerate_sessions(Manager *m) {
return r;
}
+int manager_enumerate_inhibitors(Manager *m) {
+ DIR *d;
+ struct dirent *de;
+ int r = 0;
+
+ assert(m);
+
+ d = opendir("/run/systemd/inhibit");
+ if (!d) {
+ if (errno == ENOENT)
+ return 0;
+
+ log_error("Failed to open /run/systemd/inhibit: %m");
+ return -errno;
+ }
+
+ while ((de = readdir(d))) {
+ int k;
+ Inhibitor *i;
+
+ if (!dirent_is_file(de))
+ continue;
+
+ k = manager_add_inhibitor(m, de->d_name, &i);
+ if (k < 0) {
+ log_notice("Couldn't add inhibitor %s: %s", de->d_name, strerror(-k));
+ r = k;
+ continue;
+ }
+
+ k = inhibitor_load(i);
+ if (k < 0)
+ r = k;
+ }
+
+ closedir(d);
+
+ return r;
+}
+
int manager_dispatch_seat_udev(Manager *m) {
struct udev_device *d;
int r;
@@ -853,15 +927,28 @@ void manager_cgroup_notify_empty(Manager *m, const char *cgroup) {
static void manager_pipe_notify_eof(Manager *m, int fd) {
Session *s;
+ Inhibitor *i;
assert_se(m);
assert_se(fd >= 0);
- assert_se(s = hashmap_get(m->fifo_fds, INT_TO_PTR(fd + 1)));
- assert(s->fifo_fd == fd);
- session_remove_fifo(s);
+ s = hashmap_get(m->session_fds, INT_TO_PTR(fd + 1));
+ if (s) {
+ assert(s->fifo_fd == fd);
+ session_remove_fifo(s);
+ session_stop(s);
+ return;
+ }
- session_stop(s);
+ i = hashmap_get(m->inhibitor_fds, INT_TO_PTR(fd + 1));
+ if (i) {
+ assert(i->fifo_fd == fd);
+ inhibitor_stop(i);
+ inhibitor_free(i);
+ return;
+ }
+
+ assert_not_reached("Got EOF on unknown pipe");
}
static int manager_connect_bus(Manager *m) {
@@ -1110,6 +1197,7 @@ int manager_startup(Manager *m) {
Seat *seat;
Session *session;
User *user;
+ Inhibitor *inhibitor;
Iterator i;
assert(m);
@@ -1144,6 +1232,7 @@ int manager_startup(Manager *m) {
manager_enumerate_seats(m);
manager_enumerate_users(m);
manager_enumerate_sessions(m);
+ manager_enumerate_inhibitors(m);
/* Remove stale objects before we start them */
manager_gc(m, false);
@@ -1158,6 +1247,9 @@ int manager_startup(Manager *m) {
HASHMAP_FOREACH(session, m->sessions, i)
session_start(session);
+ HASHMAP_FOREACH(inhibitor, m->inhibitors, i)
+ inhibitor_start(inhibitor);
+
return 0;
}