Open MPI logo

Hardware Locality Development Mailing List Archives

  |   Home   |   Support   |   FAQ   |   all Hardware Locality Development mailing list

Subject: [hwloc-devel] [PATCH] Replace readdir() with readdir_r()
From: Bert Wesarg (bert.wesarg_at_[hidden])
Date: 2010-03-17 17:38:46


Make the linux backend more re-entrant safe by using readdir_r() instead
of readdir().

The size calculation for the struct dirent comes from the linux man-page.

Regards,
Bert

---
 src/topology-linux.c |   25 +++++++++++++++++++++----
 1 files changed, 21 insertions(+), 4 deletions(-)
diff --git a/src/topology-linux.c b/src/topology-linux.c
index 50fe2a3..7defcae 100644
--- a/src/topology-linux.c
+++ b/src/topology-linux.c
@@ -10,6 +10,7 @@
 #include <private/private.h>
 #include <private/debug.h>
 
+#include <stddef.h>
 #include <limits.h>
 #include <stdio.h>
 #include <fcntl.h>
@@ -192,6 +193,13 @@ hwloc_opendir(const char *p, int d __hwloc_attribute_unused)
 #endif
 }
 
+static inline struct dirent *
+hwloc_dirent_alloc(DIR *dir)
+{
+    return malloc(offsetof(struct dirent, d_name) +
+            fpathconf(dirfd(dir), _PC_NAME_MAX) + 1);
+}
+
 int
 hwloc_linux_set_tid_cpubind(hwloc_topology_t topology __hwloc_attribute_unused, pid_t tid, hwloc_const_cpuset_t hwloc_set)
 {
@@ -311,6 +319,7 @@ static int
 hwloc_linux_get_proc_tids(DIR *taskdir, unsigned *nr_tidsp, pid_t ** tidsp)
 {
   struct dirent *dirent;
+  struct dirent *dirent_storage;
   unsigned nr_tids = 0;
   unsigned max_tids = 32;
   pid_t *tids;
@@ -324,7 +333,8 @@ hwloc_linux_get_proc_tids(DIR *taskdir, unsigned *nr_tidsp, pid_t ** tidsp)
 
   rewinddir(taskdir);
 
-  while ((dirent = readdir(taskdir)) != NULL) {
+  dirent_storage = hwloc_dirent_alloc(taskdir);
+  while (readdir_r(taskdir, dirent_storage, &dirent) == 0) {
     if (nr_tids == max_tids) {
       max_tids += 8;
       tids = realloc(tids, max_tids*sizeof(pid_t));
@@ -333,6 +343,7 @@ hwloc_linux_get_proc_tids(DIR *taskdir, unsigned *nr_tidsp, pid_t ** tidsp)
       continue;
     tids[nr_tids++] = atoi(dirent->d_name);
   }
+  free(dirent_storage);
 
   *nr_tidsp = nr_tids;
   *tidsp = tids;
@@ -1166,7 +1177,8 @@ look_sysfsnode(struct hwloc_topology *topology, const char *path, unsigned *foun
   dir = hwloc_opendir(path, topology->backend_params.sysfs.root_fd);
   if (dir)
     {
-      while ((dirent = readdir(dir)) != NULL)
+      struct dirent *dirent_storage = hwloc_dirent_alloc(dir);
+      while (readdir_r(dir, dirent_storage, &dirent) == 0)
 	{
 	  unsigned long numnode;
 	  if (strncmp(dirent->d_name, "node", 4))
@@ -1176,6 +1188,7 @@ look_sysfsnode(struct hwloc_topology *topology, const char *path, unsigned *foun
 	    nbnodes = numnode+1;
 	}
       closedir(dir);
+      free(dirent_storage);
     }
 
   if (nbnodes <= 1)
@@ -1234,7 +1247,8 @@ look_sysfscpu(struct hwloc_topology *topology, const char *path)
   dir = hwloc_opendir(path, topology->backend_params.sysfs.root_fd);
   if (dir) {
     struct dirent *dirent;
-    while ((dirent = readdir(dir)) != NULL) {
+    struct dirent *dirent_storage = hwloc_dirent_alloc(dir);
+    while (readdir_r(dir, dirent_storage, &dirent) == 0) {
       unsigned long cpu;
       char online[2];
 
@@ -1276,6 +1290,7 @@ look_sysfscpu(struct hwloc_topology *topology, const char *path)
       hwloc_cpuset_set(cpuset, cpu);
     }
     closedir(dir);
+    free(dirent_storage);
   }
 
   topology->support.discovery.proc = 1;
@@ -1614,6 +1629,7 @@ hwloc_look_linux(struct hwloc_topology *topology)
   if (nodes_dir) {
     /* Kerrighed */
     struct dirent *dirent;
+    struct dirent *dirent_storage = hwloc_dirent_alloc(nodes_dir);
     char path[128];
     hwloc_obj_t machine;
     hwloc_cpuset_t machine_online_set;
@@ -1625,7 +1641,7 @@ hwloc_look_linux(struct hwloc_topology *topology)
 
     /* No cpuset support for now.  */
     /* No sys support for now.  */
-    while ((dirent = readdir(nodes_dir)) != NULL) {
+    while (readdir_r(nodes_dir, dirent_storage, &dirent) == 0) {
       unsigned long node;
       if (strncmp(dirent->d_name, "node", 4))
 	continue;
@@ -1655,6 +1671,7 @@ hwloc_look_linux(struct hwloc_topology *topology)
 			 &machine->attr->machine.dmi_board_name);
     }
     closedir(nodes_dir);
+    free(dirent_storage);
   } else {
     /* Get the machine memory attributes */
     hwloc_get_procfs_meminfo_info(topology, "/proc/meminfo", &topology->levels[0][0]->memory);
-- 
tg: (00cf78b..) bw/readdir_r (depends on: master)