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)