Here's the patch :)
Le 21/11/2010 20:49, Brice Goglin a écrit : > Le 21/11/2010 20:34, Christopher Samuel a écrit : > >> In look_powerpc_device_tree() I did similar and found that it >> never proceeds past this loop: >> >> if (('.' == dirent->d_name[0]) || (0 == (dirent->d_type & DT_DIR))) >> continue; >> >> Adding some debugging to print the name and type and whether >> they were used or skipped I see that when it fails the >> dirent->d_type is always '0', but when it works it's '4'. >> >> The manual page for readdir(3) says: >> >> # Currently, only some file systems (among them: Btrfs, >> # ext2, ext3, and ext4) have full support returning the file >> # type in d_type. All applications must properly handle >> # a return of DT_UNKNOWN. >> >> So I'm guessing that reiserfs and GPFS (both of which are >> available on this PPC64 box) are returning DT_UNKNOWN (0). >> >> So the above loop will need to catch that and, if it is >> DT_UNKNOWN, do a stat or lstat on the entry to find out >> what it is. :-( >> > Awesome! Thanks a looooot Chris. Can you remove your debugging stuff, my > debug patch, and apply the attached patch. What it does is: > * gather empty dirs in hwloc-gather-topology (already pushed to trunk) > * don't use sysfs when cpu0/topology contains nothing (pushed too) > * use stat.st_mode instead of dirent->d_type (seems to not break > anything in our standard PPC tarballs, but needs more testing) > > I hope make check works now. And "lstopo" with and without the > HWLOC_FSROOT should also both use the cpuinfo code (you should see "* > Topology extraction from /proc/cpuinfo *" very early in the debug output). > > Brice > > _______________________________________________ > hwloc-devel mailing list > hwloc-de...@open-mpi.org > http://www.open-mpi.org/mailman/listinfo.cgi/hwloc-devel >
diff --git a/src/topology-linux.c b/src/topology-linux.c index 9cdc82a..c91ae57 100644 --- a/src/topology-linux.c +++ b/src/topology-linux.c @@ -2042,12 +2042,18 @@ look_powerpc_device_tree(struct hwloc_topology *topology) struct dirent *dirent; while (NULL != (dirent = readdir(dt))) { - if (('.' == dirent->d_name[0]) || (0 == (dirent->d_type & DT_DIR))) + if ('.' == dirent->d_name[0]) continue; char cpu[sizeof(ofroot) + 1 + strlen(dirent->d_name) + 1]; snprintf(cpu, sizeof(cpu), "%s/%s", ofroot, dirent->d_name); - + struct stat statbuf; + int err; + + err = hwloc_stat(cpu, &statbuf, root_fd); + if (err < 0 || !S_ISDIR(statbuf.st_mode)) + continue; + char *device_type = hwloc_read_str(cpu, "device_type", root_fd); if (NULL == device_type) continue; @@ -2642,8 +2648,10 @@ hwloc_look_linux(struct hwloc_topology *topology) /* Gather the list of cpus now */ if (getenv("HWLOC_LINUX_USE_CPUINFO") - || hwloc_access("/sys/devices/system/cpu/cpu0/topology", R_OK, topology->backend_params.sysfs.root_fd) < 0) { - /* revert to reading cpuinfo only if /sys/.../topology unavailable (before 2.6.16) */ + || (hwloc_access("/sys/devices/system/cpu/cpu0/topology/core_siblings", R_OK, topology->backend_params.sysfs.root_fd) < 0 + && hwloc_access("/sys/devices/system/cpu/cpu0/topology/thread_siblings", R_OK, topology->backend_params.sysfs.root_fd) < 0)) { + /* revert to reading cpuinfo only if /sys/.../topology unavailable (before 2.6.16) + * or not containing anything interesting */ err = look_cpuinfo(topology, "/proc/cpuinfo", topology->levels[0][0]->online_cpuset); if (err < 0) { if (topology->is_thissystem) diff --git a/tests/linux/hwloc-gather-topology.sh.in b/tests/linux/hwloc-gather-topology.sh.in index 022b30e..536c0fc 100755 --- a/tests/linux/hwloc-gather-topology.sh.in +++ b/tests/linux/hwloc-gather-topology.sh.in @@ -45,8 +45,12 @@ destdir=`mktemp -d` savepath() { local dest="$1" local path="$2" + # gather all directories, including empty ones + find "$path" -type d 2>/dev/null | while read dir ; do \ + mkdir -p "$dest/$dir" 2>/dev/null ; \ + done + # gather all files now find "$path" -type f 2>/dev/null | while read file ; do \ - mkdir -p "$dest/"`dirname $file` ; \ cat "$file" > "$dest/$file" 2>/dev/null ; \ done }