This does multiple things at once:

 I) it uses getmntent_r(3) to parse lines from /proc/mounts

 II) while doing this, it uses the correct un-escape rules for this
     file format.

     The current code converts "\ " to " ", while linux uses a "\040" to
     " " escaping rule.

 III) it accurately finds the cpuset option for a cgroups mount point.
      The current code would fail if "cpuset" would be a substring
      of an other mount option.

I'm inclined to remove the old code. But maybe there is a reason for the
current handmade parsing and un-escape code.

Regards,
Bert

---
 config/hwloc.m4      |    3 +++
 src/topology-linux.c |   27 +++++++++++++++++++++++++++
 2 files changed, 30 insertions(+), 0 deletions(-)

diff --git a/config/hwloc.m4 b/config/hwloc.m4
index 602f112..a893616 100644
--- a/config/hwloc.m4
+++ b/config/hwloc.m4
@@ -275,6 +275,9 @@ AC_DEFUN([HWLOC_INIT],[
           ])
       ], [], [[#include <curses.h>]])
     ])
+    AC_CHECK_HEADERS([mntent.h], [
+      AC_CHECK_FUNCS([getmntent_r])
+    ])
     LIBS="$old_LIBS"

     AC_CHECK_TYPES([KAFFINITY,
diff --git a/src/topology-linux.c b/src/topology-linux.c
index f8d22d3..0fb9446 100644
--- a/src/topology-linux.c
+++ b/src/topology-linux.c
@@ -21,6 +21,9 @@
 #include <sys/stat.h>
 #include <sched.h>
 #include <pthread.h>
+#if defined(HAVE_GETMNTENT_R) && HAVE_GETMNTENT_R
+#include <mntent.h>
+#endif

 #ifndef HWLOC_HAVE_CPU_SET
 /* libc doesn't have support for sched_setaffinity, build system call
@@ -755,6 +758,9 @@ hwloc_find_linux_cpuset_mntpnt(char **cgroup_mntpnt, char 
**cpuset_mntpnt, int f
 #define PROC_MOUNT_LINE_LEN 128
   char line[PROC_MOUNT_LINE_LEN];
   FILE *fd;
+#if defined(HAVE_GETMNTENT_R) && HAVE_GETMNTENT_R
+  struct mntent ent;
+#endif

   *cgroup_mntpnt = NULL;
   *cpuset_mntpnt = NULL;
@@ -763,6 +769,26 @@ hwloc_find_linux_cpuset_mntpnt(char **cgroup_mntpnt, char 
**cpuset_mntpnt, int f
   if (!fd)
     return;

+#if defined(HAVE_GETMNTENT_R) && HAVE_GETMNTENT_R
+  while (getmntent_r(fd, &ent, line, sizeof(line))) {
+    if (!strcmp(ent.mnt_type, "cpuset")) {
+      /* found a cpuset mntpnt */
+      hwloc_debug("Found cpuset mount point on %s\n", ent.mnt_dir);
+      *cpuset_mntpnt = strdup(ent.mnt_dir);
+      break;
+    } else if (!strcmp(ent.mnt_type, "cgroup")) {
+      /* found a cgroup mntpnt, look for a cpuset options */
+      char *opt, *opts = ent.mnt_opts;
+      while ((opt = strsep(&opts, ",")) && strcmp(opt, "cpuset"))
+        ; /* continue */
+      if (opt) {
+       hwloc_debug("Found cgroup/cpuset mount point on %s\n", ent.mnt_dir);
+       *cgroup_mntpnt = strdup(ent.mnt_dir);
+       break;
+      }
+    }
+  }
+#else
   while (fgets(line, sizeof(line), fd)) {
     char *path;
     char *type;
@@ -798,6 +824,7 @@ hwloc_find_linux_cpuset_mntpnt(char **cgroup_mntpnt, char 
**cpuset_mntpnt, int f
       break;
     }
   }
+#endif

   fclose(fd);
 }
-- 
tg: (e66476e..) bw/getmntent (depends on: master)

Reply via email to