logind: rework allocation/freeing of inhibitors

Let's follow our modern style (i.e. return proper errors, use structure
initialization and _cleanup_).

Most importantly: remove state file and FIFO removal from
inhibitor_free() and let's move it to inhibitor_stop().

This makes sure that state files/FIFOs are not removed when the we
terminate logind, i.e. that they can survive logind restarts.

Fixes: #11825
This commit is contained in:
Lennart Poettering
2019-07-23 16:08:06 +02:00
parent 09f300c4d0
commit 81280b2a6f
3 changed files with 48 additions and 37 deletions
+8 -12
View File
@@ -197,26 +197,22 @@ 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, p->pw_dir, _user);
}
int manager_add_inhibitor(Manager *m, const char* id, Inhibitor **_inhibitor) {
int manager_add_inhibitor(Manager *m, const char* id, Inhibitor **ret) {
Inhibitor *i;
int r;
assert(m);
assert(id);
i = hashmap_get(m->inhibitors, id);
if (i) {
if (_inhibitor)
*_inhibitor = i;
return 0;
if (!i) {
r = inhibitor_new(&i, m, id);
if (r < 0)
return r;
}
i = inhibitor_new(m, id);
if (!i)
return -ENOMEM;
if (_inhibitor)
*_inhibitor = i;
if (ret)
*ret = i;
return 0;
}
+36 -23
View File
@@ -24,48 +24,59 @@
#include "user-util.h"
#include "util.h"
Inhibitor* inhibitor_new(Manager *m, const char* id) {
Inhibitor *i;
int inhibitor_new(Inhibitor **ret, Manager *m, const char* id) {
_cleanup_(inhibitor_freep) Inhibitor *i = NULL;
int r;
assert(ret);
assert(m);
assert(id);
i = new0(Inhibitor, 1);
i = new(Inhibitor, 1);
if (!i)
return NULL;
return -ENOMEM;
*i = (Inhibitor) {
.manager = m,
.what = _INHIBIT_WHAT_INVALID,
.mode = _INHIBIT_MODE_INVALID,
.uid = UID_INVALID,
.fifo_fd = -1,
};
i->state_file = path_join("/run/systemd/inhibit", id);
if (!i->state_file)
return mfree(i);
return -ENOMEM;
i->id = basename(i->state_file);
if (hashmap_put(m->inhibitors, i->id, i) < 0) {
free(i->state_file);
return mfree(i);
}
r = hashmap_put(m->inhibitors, i->id, i);
if (r < 0)
return r;
i->manager = m;
i->fifo_fd = -1;
return i;
*ret = TAKE_PTR(i);
return 0;
}
void inhibitor_free(Inhibitor *i) {
assert(i);
Inhibitor* inhibitor_free(Inhibitor *i) {
hashmap_remove(i->manager->inhibitors, i->id);
inhibitor_remove_fifo(i);
if (!i)
return NULL;
free(i->who);
free(i->why);
if (i->state_file) {
(void) unlink(i->state_file);
free(i->state_file);
}
sd_event_source_unref(i->event_source);
safe_close(i->fifo_fd);
free(i);
/* Note that we don't remove neither the state file nor the fifo path here, since we want both to
* survive daemon restarts */
free(i->state_file);
free(i->fifo_path);
hashmap_remove(i->manager->inhibitors, i->id);
return mfree(i);
}
int inhibitor_save(Inhibitor *i) {
@@ -184,6 +195,8 @@ int inhibitor_stop(Inhibitor *i) {
i->pid, i->uid,
inhibit_mode_to_string(i->mode));
inhibitor_remove_fifo(i);
if (i->state_file)
(void) unlink(i->state_file);
+4 -2
View File
@@ -48,8 +48,10 @@ struct Inhibitor {
int fifo_fd;
};
Inhibitor* inhibitor_new(Manager *m, const char *id);
void inhibitor_free(Inhibitor *i);
int inhibitor_new(Inhibitor **ret, Manager *m, const char* id);
Inhibitor* inhibitor_free(Inhibitor *i);
DEFINE_TRIVIAL_CLEANUP_FUNC(Inhibitor*, inhibitor_free);
int inhibitor_save(Inhibitor *i);
int inhibitor_load(Inhibitor *i);