summaryrefslogtreecommitdiff
path: root/tools/perf/perf-archive.sh
blob: 7977e9b0a5eaaec8f2db40252c4125e663ca222a (plain)
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