1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146
|
#!/bin/bash
# SPDX-License-Identifier: GPL-2.0
# perf archive
# Arnaldo Carvalho de Melo <acme@redhat.com>
PERF_DATA=perf.data
PERF_SYMBOLS=perf.symbols
PERF_ALL=perf.all
ALL=0
UNPACK=0
while [ $# -gt 0 ] ; do
if [ $1 == "--all" ]; then
ALL=1
shift
elif [ $1 == "--unpack" ]; then
UNPACK=1
shift
elif [ $1 == "--exclude-buildids" ]; then
EXCLUDE_BUILDIDS="$2"
if [ ! -e "$EXCLUDE_BUILDIDS" ]; then
echo "Provided exclude-buildids file $EXCLUDE_BUILDIDS does not exist"
exit 1
fi
shift 2
else
PERF_DATA=$1
UNPACK_TAR=$1
shift
fi
done
if [ $UNPACK -eq 1 ]; then
if [ ! -z "$UNPACK_TAR" ]; then # tar given as an argument
if [ ! -e "$UNPACK_TAR" ]; then
echo "Provided file $UNPACK_TAR does not exist"
exit 1
fi
TARGET="$UNPACK_TAR"
else # search for perf tar in the current directory
TARGET=`find . -regex "\./perf.*\.tar\.bz2"`
TARGET_NUM=`echo -n "$TARGET" | grep -c '^'`
if [ -z "$TARGET" ] || [ $TARGET_NUM -gt 1 ]; then
echo -e "Error: $TARGET_NUM files found for unpacking:\n$TARGET"
echo "Provide the requested file as an argument"
exit 1
else
echo "Found target file for unpacking: $TARGET"
fi
fi
if [[ "$TARGET" =~ (\./)?$PERF_ALL.*.tar.bz2 ]]; then # perf tar generated by --all option
TAR_CONTENTS=`tar tvf "$TARGET" | tr -s " " | cut -d " " -f 6`
VALID_TAR=`echo "$TAR_CONTENTS" | grep "$PERF_SYMBOLS.tar.bz2" | wc -l` # check if it contains a sub-tar perf.symbols
if [ $VALID_TAR -ne 1 ]; then
echo "Error: $TARGET file is not valid (contains zero or multiple sub-tar files with debug symbols)"
exit 1
fi
INTERSECT=`comm -12 <(ls) <(echo "$TAR_CONTENTS") | tr "\n" " "` # check for overwriting
if [ ! -z "$INTERSECT" ]; then # prompt if file(s) already exist in the current directory
echo "File(s) ${INTERSECT::-1} already exist in the current directory."
while true; do
read -p 'Do you wish to overwrite them? ' yn
case $yn in
[Yy]* ) break;;
[Nn]* ) exit 1;;
* ) echo "Please answer yes or no.";;
esac
done
fi
# unzip the perf.data file in the current working directory and debug symbols in ~/.debug directory
tar xvf $TARGET && tar xvf $PERF_SYMBOLS.tar.bz2 -C ~/.debug
else # perf tar generated by perf archive (contains only debug symbols)
tar xvf $TARGET -C ~/.debug
fi
exit 0
fi
#
# PERF_BUILDID_DIR environment variable set by perf
# path to buildid directory, default to $HOME/.debug
#
if [ -z $PERF_BUILDID_DIR ]; then
PERF_BUILDID_DIR=~/.debug/
else
# append / to make substitutions work
PERF_BUILDID_DIR=$PERF_BUILDID_DIR/
fi
BUILDIDS=$(mktemp /tmp/perf-archive-buildids.XXXXXX)
#
# EXCLUDE_BUILDIDS is an optional file that contains build-ids to be excluded from the
# archive. It is a list of build-ids, one per line, without any leading or trailing spaces.
# If the file is empty, all build-ids will be included in the archive. To create a exclude-
# buildids file, you can use the following command:
# perf buildid-list -i perf.data --with-hits | grep -v "^ " > exclude_buildids.txt
# You can edit the file to remove the lines that you want to keep in the archive, then:
# perf archive --exclude-buildids exclude_buildids.txt
#
if [ -s "$EXCLUDE_BUILDIDS" ]; then
perf buildid-list -i $PERF_DATA --with-hits | grep -v "^ " | grep -Fv -f $EXCLUDE_BUILDIDS > $BUILDIDS
if [ ! -s "$BUILDIDS" ] ; then
echo "perf archive: no build-ids found after applying exclude-buildids file"
rm $BUILDIDS || true
exit 1
fi
else
perf buildid-list -i $PERF_DATA --with-hits | grep -v "^ " > $BUILDIDS
if [ ! -s "$BUILDIDS" ] ; then
echo "perf archive: no build-ids found"
rm $BUILDIDS || true
exit 1
fi
fi
MANIFEST=$(mktemp /tmp/perf-archive-manifest.XXXXXX)
PERF_BUILDID_LINKDIR=$(readlink -f $PERF_BUILDID_DIR)/
cut -d ' ' -f 1 $BUILDIDS | \
while read build_id ; do
linkname=$PERF_BUILDID_DIR.build-id/${build_id:0:2}/${build_id:2}
filename=$(readlink -f $linkname)
echo ${linkname#$PERF_BUILDID_DIR} >> $MANIFEST
echo ${filename#$PERF_BUILDID_LINKDIR} >> $MANIFEST
done
if [ $ALL -eq 1 ]; then # pack perf.data file together with tar containing debug symbols
HOSTNAME=$(hostname)
DATE=$(date '+%Y%m%d-%H%M%S')
tar cjf $PERF_SYMBOLS.tar.bz2 -C $PERF_BUILDID_DIR -T $MANIFEST
tar cjf $PERF_ALL-$HOSTNAME-$DATE.tar.bz2 $PERF_DATA $PERF_SYMBOLS.tar.bz2
rm $PERF_SYMBOLS.tar.bz2 $MANIFEST $BUILDIDS || true
else # pack only the debug symbols
tar cjf $PERF_DATA.tar.bz2 -C $PERF_BUILDID_DIR -T $MANIFEST
rm $MANIFEST $BUILDIDS || true
fi
echo -e "Now please run:\n"
echo -e "$ perf archive --unpack\n"
echo "or unpack the tar manually wherever you need to run 'perf report' on."
exit 0
|