]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
logind: rework allocation/freeing of inhibitors
authorLennart Poettering <lennart@poettering.net>
Tue, 23 Jul 2019 08:27:19 +0000 (10:27 +0200)
committerLennart Poettering <lennart@poettering.net>
Tue, 23 Jul 2019 14:08:06 +0000 (16:08 +0200)
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
src/login/logind-core.c
src/login/logind-inhibit.c
src/login/logind-inhibit.h

index f631ba7219ceb7ad0f7c9a9e3c0ce0eaa2d97a79..1d21e90a2eaa905aa324e8f3d6051397d53d07f0 100644 (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;
 }
index 8716a9f091ef2161f9e89f3887111b663e306f8c..11cbb4534c5159fcf0374850aa531c42d28be63c 100644 (file)
 #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);
-        }
-
-        i->manager = m;
-        i->fifo_fd = -1;
+        r = hashmap_put(m->inhibitors, i->id, i);
+        if (r < 0)
+                return r;
 
-        return i;
+        *ret = TAKE_PTR(i);
+        return 0;
 }
 
-void inhibitor_free(Inhibitor *i) {
-        assert(i);
-
-        hashmap_remove(i->manager->inhibitors, i->id);
+Inhibitor* inhibitor_free(Inhibitor *i) {
 
-        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);
 
index 650587106da77d1b61ca0f099fc8d31ce385f888..a5cec63ecd36ea14735ad113fcf2c703c7a4b51e 100644 (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);