about summary refs log tree commit homepage
diff options
context:
space:
mode:
authorEric Wong <normalperson@yhbt.net>2013-02-08 08:48:36 +0000
committerEric Wong <normalperson@yhbt.net>2013-02-08 08:48:36 +0000
commite427fb773837953c01ebe8dfaf8f8679c7895fc2 (patch)
tree5008c15a3a2ebf8e7fee043ae9880a8a7cd7568c
parent223adf17682765f9e72d3436348700085d823a6e (diff)
downloadcmogstored-e427fb773837953c01ebe8dfaf8f8679c7895fc2.tar.gz
This centralizes the mountpoint suitability logic in
one place.  In the future, it may also allow us to
parallelize the work of scanning filesystems.
-rw-r--r--mnt.c35
-rw-r--r--mnt.h2
-rw-r--r--mnt_usable.c44
3 files changed, 44 insertions, 37 deletions
diff --git a/mnt.c b/mnt.c
index e5c3244..5acb75c 100644
--- a/mnt.c
+++ b/mnt.c
@@ -62,24 +62,11 @@ static Hash_table * mnt_new(size_t n)
         return rv;
 }
 
-static bool resolve_symlink(char **orig)
-{
-        char *p = canonicalize_filename_mode(*orig, CAN_EXISTING);
-
-        if (p) {
-                free(*orig);
-                *orig = p;
-                return true;
-        }
-        return false;
-}
-
 /* populates a hash table starting with the mount list */
 static void mnt_populate(Hash_table *tbl)
 {
         struct mount_entry *head = read_file_system_list(false);
         struct mount_entry *next;
-        struct stat sb;
         union {
                 const void *ptr;
                 struct mount_entry *old_me;
@@ -98,29 +85,9 @@ static void mnt_populate(Hash_table *tbl)
                 }
                 head->me_type = NULL;
 
-                if (head->me_dummy)
-                        goto skip;
-                if (!mog_mnt_usable(head->me_mountdir))
+                if (!mog_mnt_usable(head))
                         goto skip;
 
-                /* the device number may not have been populated, do it */
-                if (head->me_dev == (dev_t)-1) {
-                        if (stat(head->me_mountdir, &sb) != 0)
-                                goto skip;
-                        head->me_dev = sb.st_dev;
-                }
-
-                /*
-                 * resolve symlinks for things that look like paths
-                 * and skip dead symlinks
-                 */
-                if (head->me_devname[0] == '/') {
-                        if (lstat(head->me_devname, &sb) == 0 &&
-                            S_ISLNK(sb.st_mode) &&
-                            ! resolve_symlink(&head->me_devname))
-                                goto skip;
-                }
-
                 /* mark the device as something we _might_ track util for */
                 mog_iou_active(head->me_dev);
 
diff --git a/mnt.h b/mnt.h
index 6310fd9..ee82cd0 100644
--- a/mnt.h
+++ b/mnt.h
@@ -9,4 +9,4 @@ void mog_mnt_update_util(struct mog_iostat *);
 char *mog_mnt_fetch_util(dev_t st_dev, char dst[MOG_IOUTIL_LEN]);
 
 /* mnt_usable.c */
-bool mog_mnt_usable(const char *path);
+bool mog_mnt_usable(struct mount_entry *me);
diff --git a/mnt_usable.c b/mnt_usable.c
index 1d590b1..9ba52e4 100644
--- a/mnt_usable.c
+++ b/mnt_usable.c
@@ -16,18 +16,58 @@
 #define MY_STATFS statvfs
 #endif
 
+static bool resolve_symlink(char **orig)
+{
+        char *p = canonicalize_filename_mode(*orig, CAN_EXISTING);
+
+        if (p) {
+                free(*orig);
+                *orig = p;
+                return true;
+        }
+        return false;
+}
+
+static bool stat_harder(struct mount_entry *me)
+{
+        struct stat sb;
+
+        /* the device number may not have been populated, do it */
+        if (me->me_dev == (dev_t)-1) {
+                if (stat(me->me_mountdir, &sb) != 0)
+                        return false;
+                me->me_dev = sb.st_dev;
+        }
+
+        /*
+         * resolve symlinks for things that look like paths
+         * and skip dead symlinks
+         */
+        if (me->me_devname[0] == '/') {
+                if (lstat(me->me_devname, &sb) == 0
+                    && S_ISLNK(sb.st_mode)
+                    && ! resolve_symlink(&me->me_devname))
+                        return false;
+        }
+        return true;
+}
+
 /*
  * prevents us from using filesystems of unknown size, since those could
  * be stalled/dead network mounts
  */
-bool mog_mnt_usable(const char *path)
+bool mog_mnt_usable(struct mount_entry *me)
 {
         struct MY_STATFS buf;
+        const char *path = me->me_mountdir;
+
+        if (me->me_dummy)
+                return false;
 
 retry:
         errno = 0;
         if (MY_STATFS(path, &buf) == 0)
-                return (buf.f_blocks > 0);
+                return (buf.f_blocks > 0) ? stat_harder(me) : false;
 
         /* unknown */
         assert(errno != EFAULT && "BUG: EFAULT from statfs/statvfs");