[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