1#!/bin/sh 2#-*-sh-*- 3 4# 5# Copyright © 2009 CNRS 6# Copyright © 2009-2019 Inria. All rights reserved. 7# Copyright © 2009-2012 Université Bordeaux 8# See COPYING in top-level directory. 9# 10 11HWLOC_top_builddir="@HWLOC_top_builddir@" 12prefix="@prefix@" 13exec_prefix="@exec_prefix@" 14bindir="@bindir@" 15localstatedir="@localstatedir@" 16runstatedir="@HWLOC_runstatedir@" 17# this will be changed into $bindir/lstopo during make install 18lstopo="$HWLOC_top_builddir/utils/lstopo/lstopo-no-graphics" 19 20# make sure we use default numeric formats 21LANG=C 22LC_ALL=C 23export LANG LC_ALL 24 25gatherio=0 26gatherdmi=0 27 28if [ ! -x "$lstopo" ] 29then 30 error "Could not find lstopo executable in the install or build dir." 31 exit 1 32fi 33 34error() 35{ 36 echo $@ 2>&1 37} 38 39usage() 40{ 41 echo "$0 [options] <savepath>" 42 echo " Saves the Linux topology files (/sys, /proc, ...) under <savepath>.tar.bz2" 43 echo " and the corresponding lstopo verbose output under <savepath>.output" 44 echo "Options:" 45 echo " --io Gather I/O files (takes much longer and generates much larger tarball)" 46 echo " --dmi Gather SMBIOS files. Works only when run as root. Requires dmi-sysfs kernel module" 47 echo "Example:" 48 echo " $0 /tmp/\$(uname -n)" 49} 50 51while [ x`echo "$1" | cut -c1` = x- ] ; do 52 case $1 in 53 --io) gatherio=1;; 54 --dmi) gatherdmi=1;; 55 *) echo "Unrecognized option: $1"; usage; exit 1;; 56 esac 57 shift 58done 59 60if test $# -lt 1 -o x$1 = x; then 61 usage 62 exit 1 63fi 64name="$1" 65basename=`basename "$name"` 66dirname=`dirname "$name"` 67 68if [ x$gatherio = x0 ]; then 69 echo "I/O files won't be saved (--io not given)." 70fi 71if [ x$gatherdmi = x0 ]; then 72 echo "DMI files won't be saved (--dmi not given)." 73fi 74 75echo 76echo "*** Note that this tool may be slow on large nodes or when I/O is enabled. ***" 77echo 78 79if ! mkdir -p "$dirname" ; then 80 error "Failed to create directory $dirname." 81 exit 1 82fi 83 84if [ ! -w "$dirname" ] ; then 85 echo "$dirname is not writable." 86 exit 1 87fi 88 89destdir=`mktemp -d` 90 91# Use cat so that we properly get proc/sys files even if their 92# file length is wrong 93savefile() { 94 local dest="$1" 95 local file="$2" 96 if test -r "$file"; then 97 dir=`dirname "$file"` 98 mkdir -p "$dest/$dir" 2>/dev/null 99 cat "$file" > "$dest/$file" 2>/dev/null 100 fi 101} 102 103savelink() { 104 local dest="$1" 105 local file="$2" 106 dir=`dirname "$file"` 107 mkdir -p "$dest/$dir" 2>/dev/null 108 cp -P "$file" "$dest/$file" 109} 110 111# Gather the following list of files 112cat << EOF | while read -r path ; do savefile "$destdir/$basename" "$path" ; done 113/proc/cpuinfo 114/proc/meminfo 115/proc/mounts 116/proc/stat 117/proc/self/cpuset 118/proc/self/cgroup 119EOF 120 121# Get all files from the given directory 122# Ignore errors since some files may be missing, and some may be 123# restricted to root (but we don't need them). 124savedir() { 125 local dest="$1" 126 local path="$2" 127 # gather all directories, including empty ones 128 find "$path" -type d 2>/dev/null | while read -r dir ; do 129 mkdir -p "$dest/$dir" 2>/dev/null 130 done 131 # gather all files now 132 find "$path" -type f 2>/dev/null | while read -r file ; do 133 savefile "$dest" "$file" 134 done 135 # gather symlinks 136 find "$path" -type l 2>/dev/null | while read -r link ; do 137 savelink "$dest" "$link" 138 done 139} 140 141# Gather the following list of directories 142cat << EOF | while read -r path ; do savedir "$destdir/$basename" "$path" ; done 143/sys/devices/system/cpu/ 144/sys/devices/system/node/ 145/sys/bus/cpu/devices/ 146/sys/bus/node/devices/ 147/sys/class/dmi/id/ 148/sys/devices/virtual/dmi/id/ 149/sys/kernel/mm/hugepages/ 150/proc/device-tree/cpus/ 151EOF 152 153# Gather the default /var/run/hwloc (in case it was created by a system-wide hwloc-dump-hwdata) 154if test -d /var/run/hwloc; then 155 savedir "$destdir/$basename" /var/run/hwloc 156fi 157# Then, gather what the current hwloc installation could have created in a different $runstatedir 158if test "$runstatedir" != "/var/run" -a -d "$runstatedir/hwloc"; then 159 savedir "$destdir/$basename" "$runstatedir/hwloc/" 160 mkdir -p "$destdir/$basename/var/run" 161 ln -sr "$destdir/$basename/$runstatedir/hwloc" "$destdir/$basename/var/run/hwloc.runstatedir" 162fi 163# And gather what custom $HWLOC_DUMPED_HWDATA_DIR 164if test "x$HWLOC_DUMPED_HWDATA_DIR" != x -a -d "$HWLOC_DUMPED_HWDATA_DIR"; then 165 savedir "$destdir/$basename" "$HWLOC_DUMPED_HWDATA_DIR" 166 mkdir -p "$destdir/$basename/var/run" 167 ln -sr "$destdir/$basename/$HWLOC_DUMPED_HWDATA_DIR" "$destdir/$basename/var/run/hwloc.HWLOC_DUMPED_HWDATA_DIR" 168fi 169# Now link to /var/run/hwloc (used by default in lstopo -i) to something sane if needed 170if ! test -d "$destdir/$basename/var/run/hwloc"; then 171 if test -e "$destdir/$basename/var/run/hwloc.HWLOC_DUMPED_HWDATA_DIR"; then 172 ln -sr "$destdir/$basename/var/run/hwloc.HWLOC_DUMPED_HWDATA_DIR" "$destdir/$basename/var/run/hwloc" 173 else if test -e "$destdir/$basename/$runstatedir/hwloc"; then 174 ln -sr "$destdir/$basename/var/run/hwloc.runstatedir" "$destdir/$basename/var/run/hwloc" 175 fi fi 176fi 177 178# Optionally gather I/O directories too 179if [ x$gatherio = x1 ]; then 180 cat << EOF | while read -r path ; do savedir "$destdir/$basename" "$path" ; done 181/sys/bus/pci/devices/ 182/sys/bus/pci/slots/ 183/sys/block/ 184/sys/class/block/ 185/sys/class/dma/ 186/sys/class/drm/ 187/sys/class/infiniband/ 188/sys/class/net/ 189/sys/class/mic/ 190EOF 191 ls -d /sys/devices/pci* 2>/dev/null | sed -e 's@$@/@' | while read -r path ; do savedir "$destdir/$basename" "$path" ; done 192 ls -d /run/udev/data/b* 2>/dev/null | while read -r path ; do savefile "$destdir/$basename" "$path" ; done 193fi 194 195if [ x$gatherdmi = x1 ]; then 196 savedir "$destdir/$basename" /sys/firmware/dmi/ 197fi 198 199# Get an entire mount point, after decoding its path 200# we don't support path with \n since it would break in 'find ... | while read ..." above 201savemntpnt() { 202 local encodedpath=$1 203 if echo "$1" | grep "\\012" ; then 204 echo "Ignoring mount point whose filename contains an end of line." 205 return 206 fi 207 local path=$(echo "$1" | sed -e 's@\\134@\\@g' -e 's@\\040@ @g' -e 's@\\011@ @g') 208 savedir "$destdir/$basename" "${path}/" 209} 210 211# Gather cgroup/cpuset mntpnts 212cat /proc/mounts | while read -r dummy1 mntpath mnttype mntopts dummy2 ; do 213 [ x$mnttype = xcpuset ] && savemntpnt "$mntpath" 214 [ x$mnttype = xcgroup ] && echo $mntopts | grep -w cpuset >/dev/null && savemntpnt "$mntpath" 215done 216 217# export /proc/hwloc-nofile-info during lstopo (needs HWLOC_DUMP_NOFILE_INFO with HWLOC_THISSYSTEM=1) 218export HWLOC_DUMP_NOFILE_INFO="$destdir/$basename/proc/hwloc-nofile-info" 219"$lstopo" - >/dev/null 220# disable HWLOC_DUMP_NOFILE_INFO for next lstopo invocation 221export HWLOC_DUMP_NOFILE_INFO= 222 223# Create the archive and keep the tree in /tmp for testing 224( cd "$destdir/" && tar cfj "$basename.tar.bz2" "$basename" ) 225mv "$destdir/$basename.tar.bz2" "$dirname/$basename.tar.bz2" 226echo "Topology files gathered in $dirname/$basename.tar.bz2 and kept in $destdir/$basename/" 227 228# Generate the output as well 229# we need "Topology not from this system" in the output so as to make test-topology.sh happy 230export HWLOC_THISSYSTEM=0 231"$lstopo" - -v > "$dirname/$basename.output" 232echo "Expected topology output stored in $dirname/$basename.output" 233"$lstopo" -.xml --whole-io --whole-system > "$dirname/$basename.xml" 234echo "XML topology stored in in $dirname/$basename.xml" 235 236echo 237echo "WARNING: Do not post these files on a public list or website unless you" 238echo "WARNING: are sure that no information about this platform is sensitive." 239 240exit 0 241