1#!/bin/sh
2#-*-sh-*-
3
4#
5# Copyright © 2009 CNRS
6# Copyright © 2009-2012 Inria.  All rights reserved.
7# Copyright © 2009-2012 Université Bordeaux 1
8# See COPYING in top-level directory.
9#
10
11abs_top_builddir="@abs_top_builddir@"
12prefix="@prefix@"
13exec_prefix="@exec_prefix@"
14bindir="@bindir@"
15# this will be changed into $bindir/lstopo during make install
16lstopo="$abs_top_builddir/utils/lstopo-no-graphics"
17
18# make sure we use default numeric formats
19LANG=C
20LC_ALL=C
21export LANG LC_ALL
22
23error()
24{
25    echo $@ 2>&1
26}
27
28usage()
29{
30   echo "$0 <savepath>"
31   echo "  Saves the Linux topology files (/sys, /proc, ...) under <savepath>.tar.bz2"
32   echo "  and the corresponding lstopo verbose output under <savepath>.output"
33   echo "Example:"
34   echo "  $0 /tmp/\$(uname -n)"
35}
36
37name="$1"; shift
38if [ -z "$name" -o x`echo $name | cut -c1` = x- ] ; then
39  [ x$name != x -a x$name != x-h -a x$name != x--help ] && echo "Unrecognized option: $name"
40  usage
41  exit 1
42fi
43basename=`basename "$name"`
44dirname=`dirname "$name"`
45
46if ! mkdir -p "$dirname" ; then
47    error "Failed to create directory $dirname."
48    exit 1
49fi
50
51if [ ! -w  "$dirname" ] ; then
52    echo "$dirname is not writable."
53    exit 1
54fi
55
56destdir=`mktemp -d`
57
58# Use cat so that we properly get proc/sys files even if their
59# file length is wrong
60savefile() {
61  local dest="$1"
62  local file="$2"
63  dir=`dirname "$file"`
64  mkdir -p "$dest/$dir" 2>/dev/null
65  cat "$file" > "$dest/$file" 2>/dev/null
66}
67
68savelink() {
69  local dest="$1"
70  local file="$2"
71  dir=`dirname "$file"`
72  mkdir -p "$dest/$dir" 2>/dev/null
73  cp -P "$file" "$dest/$file"
74}
75
76# Gather the following list of files
77cat << EOF | while read -r path ; do savefile "$destdir/$basename" "$path" ; done
78/proc/cpuinfo
79/proc/meminfo
80/proc/mounts
81/proc/stat
82/proc/self/cpuset
83EOF
84
85# Get all files from the given directory
86# Ignore errors since some files may be missing, and some may be
87# restricted to root (but we don't need them).
88savedir() {
89  local dest="$1"
90  local path="$2"
91  # gather all directories, including empty ones
92  find "$path" -type d 2>/dev/null | while read -r dir ; do
93    mkdir -p "$dest/$dir" 2>/dev/null
94  done
95  # gather all files now
96  find "$path" -type f 2>/dev/null | while read -r file ; do
97    savefile "$dest" "$file"
98  done
99  # gather symlinks
100  find "$path" -type l 2>/dev/null | while read -r link ; do
101    savelink "$dest" "$link"
102  done
103}
104
105# Gather the following list of directories
106cat << EOF | while read -r path ; do savedir "$destdir/$basename" "$path" ; done
107/sys/devices/system/cpu/
108/sys/devices/system/node/
109/sys/bus/cpu/devices/
110/sys/bus/node/devices/
111/sys/class/dmi/id/
112/sys/kernel/mm/hugepages/
113/proc/device-tree/cpus/
114EOF
115
116# Get an entire mount point, after decoding its path
117# we don't support path with \n since it would break in 'find ... | while read ..." above
118savemntpnt() {
119  local encodedpath=$1
120  if echo "$1" | grep "\\012" ; then
121    echo "Ignoring mount point whose filename contains an end of line."
122    return
123  fi
124  local path=$(echo "$1" | sed -e 's@\\134@\\@g' -e 's@\\040@ @g' -e 's@\\011@	@g')
125  savedir "$destdir/$basename" "${path}/"
126}
127
128# Gather cgroup/cpuset mntpnts
129cat /proc/mounts | while read -r dummy1 mntpath mnttype mntopts dummy2 ; do
130  [ x$mnttype = xcpuset ] && savemntpnt "$mntpath"
131  [ x$mnttype = xcgroup ] && echo $mntopts | grep -w cpuset >/dev/null && savemntpnt "$mntpath"
132done
133
134# Create the archive and keep the tree in /tmp for testing
135( cd "$destdir/" && tar cfj "$basename.tar.bz2" "$basename" )
136mv "$destdir/$basename.tar.bz2" "$dirname/$basename.tar.bz2"
137echo "Hierarchy gathered in $dirname/$basename.tar.bz2 and kept in $destdir/$basename/"
138
139# Generate the output as well
140if [ ! -x "$lstopo" ]
141then
142    error "Could not find lstopo executable in the install or build dir."
143    exit 1
144fi
145# we need "Topology not from this system" in the output so as to make test-topology.sh happy
146export HWLOC_THISSYSTEM=0
147"$lstopo" - -v > "$dirname/$basename.output"
148echo "Expected topology output stored in $dirname/$basename.output"
149
150exit 0
151