]> xenbits.xensource.com Git - people/andrewcoop/hwloc.git/commitdiff
Linux: allow to read uname from fake fs root
authorBrice Goglin <Brice.Goglin@inria.fr>
Mon, 27 Jan 2014 15:19:27 +0000 (16:19 +0100)
committerBrice Goglin <Brice.Goglin@inria.fr>
Thu, 30 Jan 2014 09:47:52 +0000 (10:47 +0100)
Read a new "fake" /proc/hwloc-nofile-info where we can store things
that cannot be saved as a file. Put the output of uname there when
gathering the topology and use it on input to overwrite local or
missing data.

This improves testing under tests/linux by allowing architecture
specific code to run from fake fsroot. Will be useful for advanced
cpuinfo parsing.

We manually remove /proc/hwloc-nofile-info in test-gather-topology.sh
because it only partially brings fake fsroot information.
Removing it creates the same !is_thissystem() output from the fake
fsroot and from the real machine.

Once we gather other information in /proc/hwloc-nofile-info:
* sysconf(_SC_LARGE_PAGESIZE);
* hwloc_getpagesize();
* hwloc_fallback_nbprocessors(topology);
we may be able to really use /proc/hwloc-nofile-info in test-gather-topology.sh
and really discover the exact same thing from the saved topology and
from the original machine. We'll see that later.

src/topology-linux.c
tests/linux/gather/test-gather-topology.sh.in
tests/linux/hwloc-gather-topology.in

index 9104a012a38e69fc089d277f8d2a322492702c5f..ba1981e540cc56b06b355988a1704ae183cbf721 100644 (file)
@@ -40,6 +40,9 @@
 struct hwloc_linux_backend_data_s {
   int root_fd; /* The file descriptor for the file system root, used when browsing, e.g., Linux' sysfs and procfs. */
   int is_real_fsroot; /* Boolean saying whether root_fd points to the real filesystem root of the system */
+
+  struct utsname utsname; /* fields contain \0 when unknown */
+
   int deprecated_classlinks_model; /* -2 if never tried, -1 if unknown, 0 if new (device contains class/name), 1 if old (device contains class:name) */
   int mic_need_directlookup; /* if not tried yet, 0 if not needed, 1 if needed */
   unsigned mic_directlookup_id_max; /* -1 if not tried yet, 0 if none to lookup, maxid+1 otherwise */
@@ -3464,6 +3467,78 @@ hwloc_linux_fallback_pu_level(struct hwloc_topology *topology)
     hwloc_setup_pu_level(topology, 1);
 }
 
+static void
+hwloc_gather_system_info(struct hwloc_topology *topology,
+                        struct hwloc_linux_backend_data_s *data)
+{
+  FILE *file;
+  char line[128]; /* enough for utsname fields */
+  char *env;
+
+  /* initialize to something sane */
+  memset(&data->utsname, 0, sizeof(data->utsname));
+
+  /* read thissystem info */
+  if (topology->is_thissystem)
+    uname(&data->utsname);
+
+  /* overwrite with optional /proc/hwloc-nofile-info */
+  file = hwloc_fopen("/proc/hwloc-nofile-info", "r", data->root_fd);
+  if (file) {
+    while (fgets(line, sizeof(line), file)) {
+      char *tmp = strchr(line, '\n');
+      if (!strncmp("OSName: ", line, 8)) {
+       if (tmp)
+         *tmp = '\0';
+       strncpy(data->utsname.sysname, line+8, sizeof(data->utsname.sysname));
+       data->utsname.sysname[sizeof(data->utsname.sysname)-1] = '\0';
+      } else if (!strncmp("OSRelease: ", line, 11)) {
+       if (tmp)
+         *tmp = '\0';
+       strncpy(data->utsname.release, line+11, sizeof(data->utsname.release));
+       data->utsname.release[sizeof(data->utsname.release)-1] = '\0';
+      } else if (!strncmp("OSVersion: ", line, 11)) {
+       if (tmp)
+         *tmp = '\0';
+       strncpy(data->utsname.version, line+11, sizeof(data->utsname.version));
+       data->utsname.version[sizeof(data->utsname.version)-1] = '\0';
+      } else if (!strncmp("HostName: ", line, 10)) {
+       if (tmp)
+         *tmp = '\0';
+       strncpy(data->utsname.nodename, line+10, sizeof(data->utsname.nodename));
+       data->utsname.nodename[sizeof(data->utsname.nodename)-1] = '\0';
+      } else if (!strncmp("Architecture: ", line, 14)) {
+       if (tmp)
+         *tmp = '\0';
+       strncpy(data->utsname.machine, line+14, sizeof(data->utsname.machine));
+       data->utsname.machine[sizeof(data->utsname.machine)-1] = '\0';
+      } else {
+       hwloc_debug("ignored /proc/hwloc-nofile-info line %s\n", line);
+       /* ignored */
+      }
+    }
+    fclose(file);
+  }
+
+  env = getenv("HWLOC_DUMP_NOFILE_INFO");
+  if (env && *env) {
+    file = fopen(env, "w");
+    if (file) {
+      if (*data->utsname.sysname)
+       fprintf(file, "OSName: %s\n", data->utsname.sysname);
+      if (*data->utsname.release)
+       fprintf(file, "OSRelease: %s\n", data->utsname.release);
+      if (*data->utsname.version)
+       fprintf(file, "OSVersion: %s\n", data->utsname.version);
+      if (*data->utsname.nodename)
+       fprintf(file, "HostName: %s\n", data->utsname.nodename);
+      if (*data->utsname.machine)
+       fprintf(file, "Architecture: %s\n", data->utsname.machine);
+      fclose(file);
+    }
+  }
+}
+
 static int
 hwloc_look_linuxfs(struct hwloc_backend *backend)
 {
@@ -3478,6 +3553,8 @@ hwloc_look_linuxfs(struct hwloc_backend *backend)
     /* somebody discovered things */
     return 0;
 
+  hwloc_gather_system_info(topology, data);
+
   hwloc_alloc_obj_cpusets(topology->levels[0][0]);
 
   /* Gather the list of admin-disabled cpus and mems */
@@ -3589,9 +3666,8 @@ hwloc_look_linuxfs(struct hwloc_backend *backend)
 
   hwloc__linux_get_mic_sn(topology, data);
 
-  /* gather uname info if fsroot wasn't changed */
-  if (topology->is_thissystem)
-    hwloc_add_uname_info(topology, NULL);
+  /* data->utsname was filled with real uname or \0, we can safely pass it */
+  hwloc_add_uname_info(topology, &data->utsname);
 
   return 1;
 }
index 572d928313b35692000e61a8a2881b9d9e20f2b8..7735646856372eecbd37836bd317d2690029b074 100755 (executable)
@@ -2,7 +2,7 @@
 #-*-sh-*-
 
 #
-# Copyright © 2012-2013 Inria.  All rights reserved.
+# Copyright © 2012-2014 Inria.  All rights reserved.
 # Copyright © 2010 Cisco Systems, Inc.  All rights reserved.
 # Copyright © 2011 Université Bordeaux 1
 # See COPYING in top-level directory.
@@ -68,6 +68,8 @@ if ! ( cd "$tmpdir" && tar xfj save.tar.bz2 ) ; then
 fi
 export HWLOC_FSROOT="$tmpdir/save"
 
+rm -f "$tmpdir/save/proc/hwloc-nofile-info"
+
 echo "Saving tarball topology to XML..."
 if ! "$lstopo" --no-io "$tmpdir/save2.xml" ; then
     error "Failed"
index bffa794320a9a92ea88907427cd04d3305818382..c3a635696a6f55e754efefc1ea99c4ee297fe9a5 100755 (executable)
@@ -3,7 +3,7 @@
 
 #
 # Copyright © 2009 CNRS
-# Copyright © 2009-2013 Inria.  All rights reserved.
+# Copyright © 2009-2014 Inria.  All rights reserved.
 # Copyright © 2009-2012 Université Bordeaux 1
 # See COPYING in top-level directory.
 #
@@ -22,6 +22,12 @@ export LANG LC_ALL
 
 gatherio=0
 
+if [ ! -x "$lstopo" ]
+then
+    error "Could not find lstopo executable in the install or build dir."
+    exit 1
+fi
+
 error()
 {
     echo $@ 2>&1
@@ -158,17 +164,18 @@ cat /proc/mounts | while read -r dummy1 mntpath mnttype mntopts dummy2 ; do
   [ x$mnttype = xcgroup ] && echo $mntopts | grep -w cpuset >/dev/null && savemntpnt "$mntpath"
 done
 
+# export /proc/hwloc-nofile-info during lstopo (needs HWLOC_DUMP_NOFILE_INFO with HWLOC_THISSYSTEM=1)
+export HWLOC_DUMP_NOFILE_INFO="$destdir/$basename/proc/hwloc-nofile-info"
+"$lstopo" - >/dev/null
+# disable HWLOC_DUMP_NOFILE_INFO for next lstopo invocation
+export HWLOC_DUMP_NOFILE_INFO=
+
 # Create the archive and keep the tree in /tmp for testing
 ( cd "$destdir/" && tar cfj "$basename.tar.bz2" "$basename" )
 mv "$destdir/$basename.tar.bz2" "$dirname/$basename.tar.bz2"
 echo "Hierarchy gathered in $dirname/$basename.tar.bz2 and kept in $destdir/$basename/"
 
 # Generate the output as well
-if [ ! -x "$lstopo" ]
-then
-    error "Could not find lstopo executable in the install or build dir."
-    exit 1
-fi
 # we need "Topology not from this system" in the output so as to make test-topology.sh happy
 export HWLOC_THISSYSTEM=0
 "$lstopo" - -v > "$dirname/$basename.output"