If a machine has a /proc/mounts file larger than 4kb and the hugetlb mount point
is after the 4kb mark the library currently fails to find the hugetlb mount.
This patch ensures that the entire mounts file is searched for the hugetlb mount
before giving up.  This patch also records the hpage_size for the specified
mount point when it is found.

Signed-off-by: Eric Munson <[EMAIL PROTECTED]>

---
V2
Changes from V1:
Use statfs to save the hugepage size when we find a mount point.

 hugeutils.c |  111 ++++++++++++++++++++++++++++++++++++++++++++----------------
 init.c      |    2 +
 2 files changed, 84 insertions(+), 29 deletions(-)

diff -upNr libhugetlbfs.orig/hugeutils.c libhugetlbfs-dev-20080516/hugeutils.c
--- libhugetlbfs.orig/hugeutils.c       2008-05-16 13:52:41.000000000 -0700
+++ libhugetlbfs-dev-20080516/hugeutils.c       2008-06-11 16:23:54.000000000 
-0700
@@ -158,13 +158,38 @@ int hugetlbfs_test_path(const char *moun
 }
 
 #define MOUNTS_SZ      4096
+#define READ_SZ                (MOUNTS_SZ - 1)
+
+static const char *path_search(char *buf)
+{
+       int err;
+       char *tmp = buf;
+       while (tmp) {
+               err = sscanf(tmp,
+                    "%*s %" stringify(PATH_MAX)
+                    "s hugetlbfs ",
+                    htlb_mount);
+               if ((err == 1) && (hugetlbfs_test_path(htlb_mount) == 1))
+                       return htlb_mount;
+
+               memset(htlb_mount, 0, sizeof(htlb_mount));
+
+               tmp = strchr(tmp, '\n');
+               if (tmp)
+                       tmp++;
+       }
+       return NULL;
+}
 
 const char *hugetlbfs_find_path(void)
 {
        int err, readerr;
-       char *tmp;
+       char *start, *newline = NULL, *end = NULL;
+       const char *tmp;
+       char hold;
        int fd, len;
        char buf[MOUNTS_SZ];
+       struct statfs statfs_buf;
 
        /* Have we already located a mount? */
        if (*htlb_mount)
@@ -183,7 +208,7 @@ const char *hugetlbfs_find_path(void)
                        return NULL;
                }
                strncpy(htlb_mount, tmp, sizeof(htlb_mount)-1);
-               return htlb_mount;
+               goto found;
        }
 
        /* Oh well, let's go searching for a mountpoint */
@@ -197,39 +222,67 @@ const char *hugetlbfs_find_path(void)
                }
        }
 
-       len = read(fd, buf, sizeof(buf));
-       readerr = errno;
-       close(fd);
-       if (len < 0) {
-               ERROR("Error reading mounts (%s)\n", strerror(errno));
-               return NULL;
-       }
-       if (len >= sizeof(buf)) {
-               ERROR("/proc/mounts is too long\n");
-               return NULL;
-       }
-       buf[sizeof(buf)-1] = '\0';
-
-       tmp = buf;
-       while (tmp) {
-               err = sscanf(tmp,
-                            "%*s %" stringify(PATH_MAX)
-                            "s hugetlbfs ",
-                            htlb_mount);
-               if ((err == 1) && (hugetlbfs_test_path(htlb_mount) == 1))
-                       return htlb_mount;
-
-               memset(htlb_mount, 0, sizeof(htlb_mount));
+       start = buf;
+       do {
+               len = read(fd, start, READ_SZ - (end - newline));
+               readerr = errno;
+               if (len < 0) {
+                       if (readerr == EAGAIN || readerr == EINTR)
+                               continue;
+                       ERROR("Error reading mounts (%s)\n", strerror(errno));
+                       close(fd);
+                       return NULL;
+               }
 
-               tmp = strchr(tmp, '\n');
-               if (tmp)
-                       tmp++;
-       }
+               if (len == 0) {
+                       buf[READ_SZ] = '\0';
+                       tmp = path_search(buf);
+                       if (tmp) {
+                               close(fd);
+                               goto found;
+                       }
+               } else {
+                       /*
+                        * There is more to read so we will examine the buffer
+                        * that we have for the hugetlb entry, if we find it
+                        * go out, otherwise pull the next chunk.
+                        */
+
+                       newline = end = start + len;
+                       while (*newline != '\n' && newline > start)
+                               newline--;
+                       if (newline <= start) {
+                               ERROR("/proc/mounts is not readable.\n");
+                               close(fd);
+                               return NULL;
+                       }
+
+                       newline++;
+                       hold = *newline;
+                       *newline = '\0';
+                       tmp = path_search(buf);
+                       if (tmp) {
+                               close(fd);
+                               goto found;
+                       }
+
+                       *newline = hold;
+                       memcpy(buf, newline, end - newline);
+                       start = buf + (end - newline);
+               }
+       } while (len != 0);
 
+       close(fd);
+       memset(htlb_mount, 0, sizeof(htlb_mount));
        WARNING("Could not find hugetlbfs mount point in /proc/mounts. "
                        "Is it mounted?\n");
 
        return NULL;
+
+found:
+       statfs(htlb_mount, &statfs_buf);
+       hpage_size = statfs_buf.f_bsize;
+       return htlb_mount;
 }
 
 int hugetlbfs_unlinked_fd(void)
diff -upNr libhugetlbfs.orig/init.c libhugetlbfs-dev-20080516/init.c
--- libhugetlbfs.orig/init.c    2008-05-16 13:52:41.000000000 -0700
+++ libhugetlbfs-dev-20080516/init.c    2008-06-11 16:25:53.000000000 -0700
@@ -18,10 +18,12 @@
  */
 
 #include "libhugetlbfs_internal.h"
+#include "hugetlbfs.h"
 
 static void __attribute__ ((constructor)) setup_libhugetlbfs(void)
 {
        __hugetlbfs_setup_debug();
+       hugetlbfs_find_path();
 #ifndef NO_ELFLINK
        __hugetlbfs_setup_elflink();
 #endif

Attachment: signature.asc
Description: Digital signature

-------------------------------------------------------------------------
Check out the new SourceForge.net Marketplace.
It's the best place to buy or sell services for
just about anything Open Source.
http://sourceforge.net/services/buy/index.php
_______________________________________________
Libhugetlbfs-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/libhugetlbfs-devel

Reply via email to