[systemd-devel] [PATCH 5/6] systemd: add Hashmap mount_unit_by_mnt_id

Ian Kent ikent at redhat.com
Mon Jul 27 04:58:34 UTC 2020


From: Ian Kent <raven at themaw.net>

When kernelwatch notification handling is added it will be necessary
to find the Mount unit from the mount id to update individual Mount
state.

Add a Hashmap to lookup the Unit to get the Mount given a MountParameters
mount id.

Signed-off-by: Ian Kent <raven at themaw.net>
---
 src/core/mount.c |   66 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 66 insertions(+)

diff --git a/src/core/mount.c b/src/core/mount.c
index 92a73f4cdb..45b5b0c1ec 100644
--- a/src/core/mount.c
+++ b/src/core/mount.c
@@ -57,6 +57,8 @@ static void mount_update_unit_state(Mount *m, Set *gone, Set *around);
 static int mount_setup_unit(Manager *m, int mnt_id, const char *what, const char *where, const char *options, const char *fstype, bool set_flags);
 static int mount_process_proc_self_mountinfo(Manager *m);
 
+static Hashmap *mount_unit_by_mnt_id = NULL;
+
 static bool MOUNT_STATE_WITH_PROCESS(MountState state) {
         return IN_SET(state,
                       MOUNT_MOUNTING,
@@ -145,6 +147,67 @@ static bool mount_needs_quota(const MountParameters *p) {
                                  "usrquota\0" "grpquota\0" "quota\0" "usrjquota\0" "grpjquota\0");
 }
 
+static int mount_hash_put_mnt_id(Mount *m, int mnt_id) {
+        Mount *mnt;
+
+        assert(m);
+
+        if (!mount_unit_by_mnt_id) {
+                mount_unit_by_mnt_id = hashmap_new(NULL);
+                if (!mount_unit_by_mnt_id)
+                        return -ENOMEM;
+        }
+
+        mnt = hashmap_get(mount_unit_by_mnt_id, INT_TO_PTR(mnt_id));
+        if (mnt)
+                return 0;
+        return hashmap_put(mount_unit_by_mnt_id, INT_TO_PTR(mnt_id), m);
+}
+
+static int mount_hash_remove_mnt_id(Mount *m) {
+        MountParameters *p;
+        Mount *mnt;
+
+        assert(m);
+
+        if (!mount_unit_by_mnt_id)
+                return 0;
+
+        p = &m->parameters_proc_self_mountinfo;
+
+        mnt = hashmap_get(mount_unit_by_mnt_id, INT_TO_PTR(p->mnt_id));
+        if (!mnt)
+                return 0;
+
+        if (p->mnt_id == -1)
+                return 0;
+
+        (void) hashmap_remove(mount_unit_by_mnt_id, INT_TO_PTR(p->mnt_id));
+
+        return 0;
+}
+
+static int mount_hash_replace_mnt_id(Mount *m, int mnt_id) {
+        Mount *mnt;
+        int r = 0;
+
+        assert(m);
+
+        if (!mount_unit_by_mnt_id) {
+                mount_unit_by_mnt_id = hashmap_new(NULL);
+                if (!mount_unit_by_mnt_id)
+                        return -ENOMEM;
+        }
+
+        mnt = hashmap_get(mount_unit_by_mnt_id, INT_TO_PTR(mnt_id));
+        if (!mnt)
+                r = mount_hash_put_mnt_id(m, mnt_id);
+        else if (mnt != m)
+                r = hashmap_replace(mount_unit_by_mnt_id, INT_TO_PTR(mnt_id), m);
+
+        return r;
+}
+
 static void mount_init(Unit *u) {
         Mount *m = MOUNT(u);
 
@@ -225,6 +288,7 @@ static void mount_done(Unit *u) {
 
         m->where = mfree(m->where);
 
+        mount_hash_remove_mnt_id(m);
         mount_parameters_done(&m->parameters_proc_self_mountinfo);
         mount_parameters_done(&m->parameters_fragment);
 
@@ -269,6 +333,8 @@ static int update_parameters_proc_self_mountinfo(
 
         p = &m->parameters_proc_self_mountinfo;
 
+        mount_hash_replace_mnt_id(m, mnt_id);
+
         p->mnt_id = mnt_id;
 
         r = free_and_strdup(&p->what, what);




More information about the systemd-devel mailing list