about summary refs log tree commit homepage
path: root/mnt.c
diff options
context:
space:
mode:
Diffstat (limited to 'mnt.c')
-rw-r--r--mnt.c24
1 files changed, 24 insertions, 0 deletions
diff --git a/mnt.c b/mnt.c
index 7205c2c..4f5aeb7 100644
--- a/mnt.c
+++ b/mnt.c
@@ -285,9 +285,12 @@ void mog_mnt_release(const struct mount_entry *me)
         CHECK(int, 0, pthread_mutex_unlock(&by_dev_lock) );
 }
 
+#define MOG_DEV_T_INVAL ((dev_t)-1)
+
 struct mnt_update {
         const char *prefix;
         size_t prefixlen;
+        dev_t st_rdev;
         char util[MOG_IOUTIL_LEN];
 };
 
@@ -297,6 +300,10 @@ struct mnt_update {
  */
 static bool me_update_match(struct mount_entry *me, struct mnt_update *update)
 {
+        if (update->st_rdev != MOG_DEV_T_INVAL
+            && me->me_dev == update->st_rdev)
+                return true;
+
         if (strlen(me->me_devname) < update->prefixlen)
                 return false;
         return memcmp(update->prefix, me->me_devname, update->prefixlen) == 0;
@@ -334,10 +341,27 @@ static bool update_util_each(void *ent, void *upd)
 void mog_mnt_update_util(struct mog_iostat *iostat)
 {
         struct mnt_update update;
+        struct stat st;
         const char *devsuffix = iostat->dev;
 
         update.prefix = xasprintf("/dev/%s", devsuffix);
         update.prefixlen = strlen(update.prefix);
+
+        /*
+         * st_rdev matching is necessary for cryptmount(8) on Linux, where
+         * /dev/mapper/FOO is NOT a symlink to /dev/dm-N, but /dev/dm-N
+         * and /dev/mapper/FOO both refer to the same device (where
+         * /dev/mapper/FOO is the mounted device name, mountlist never
+         * sees /dev/dm-N).
+         *
+         * FIXME: parse /proc/partitions under Linux like mogstored does
+         * may avoid this stat.
+         */
+        if (stat(update.prefix, &st) == 0 && S_ISBLK(st.st_mode))
+                update.st_rdev = st.st_rdev;
+        else
+                update.st_rdev = MOG_DEV_T_INVAL;
+
         assert(sizeof(update.util) == sizeof(iostat->util));
         memcpy(&update.util, iostat->util, sizeof(update.util));