]>
Commit | Line | Data |
---|---|---|
1 | #! /bin/bash | |
2 | ||
3 | # This file is part of systemtap, and is free software. You can | |
4 | # redistribute it and/or modify it under the terms of the GNU General | |
5 | # Public License (GPL); either version 2, or (at your option) any | |
6 | # later version. | |
7 | ||
8 | ||
9 | LANG=C; export LANG | |
10 | PATH=/usr/sbin:/sbin:/usr/bin:/bin:$PATH; export PATH | |
11 | ||
12 | check_error() { if test $1 != 0; then printf "\n$2\n"; exit $1; fi } | |
13 | ||
14 | help() | |
15 | { | |
16 | cat <<'EOF' | |
17 | Usage: stap-prep [OPTION]... [custom_uname] | |
18 | prepare system for systemtap use | |
19 | ||
20 | Options: | |
21 | [-q|--quiet] | |
22 | [-h|--help] | |
23 | [custom_uname] | |
24 | EOF | |
25 | } | |
26 | ||
27 | UNAME=`uname -r` # determine the kernel running on the machine | |
28 | ||
29 | # Suppress verbose output and progress indicators | |
30 | bequiet=false | |
31 | ||
32 | while [ $# -gt 0 ]; do | |
33 | case "$1" in | |
34 | -q|--quiet) | |
35 | bequiet=true | |
36 | ;; | |
37 | -h|--help) | |
38 | help | |
39 | done=true | |
40 | ;; | |
41 | *) | |
42 | UNAME=$1 | |
43 | shift | |
44 | break | |
45 | ;; | |
46 | esac | |
47 | shift | |
48 | done | |
49 | ||
50 | # help given | |
51 | if [ "$done" = "true" ]; then exit 0; fi | |
52 | ||
53 | UNAME=`echo $UNAME | sed "s/ //"` #strip out any whitespace | |
54 | echo "Configuring for kernel release $UNAME" | |
55 | ||
56 | ||
57 | # See if the configured debuginfod | |
58 | DEBUGINFOD=0 | |
59 | prep_debuginfod() { | |
60 | # Choose a representative part - the vmlinuz file itself, which | |
61 | # may be compressed-ELF or something else. Previously, used a | |
62 | # vdso* image only, but that false-positive tricks stap-prep on | |
63 | # aarch64/s390x, due to rhbz 1891509 / elfutils PR25498 | |
64 | vmlinuz=/lib/modules/$UNAME/vmlinuz | |
65 | ||
66 | if [ -n "$DEBUGINFOD_URLS" ]; then | |
67 | echo "Please wait, attempting to download $vmlinuz debuginfo" | |
68 | if [ -z "$DEBUGINFOD_TIMEOUT" ]; then | |
69 | DEBUGINFOD_TIMEOUT=300 | |
70 | export DEBUGINFOD_TIMEOUT | |
71 | echo "Increasing DEBUGINFOD_TIMEOUT to $DEBUGINFOD_TIMEOUT temporarily" | |
72 | fi | |
73 | # DEBUGINFOD_PROGRESS=1 | |
74 | # export DEBUGINFOD_PROGRESS | |
75 | if debuginfod-find debuginfo "$vmlinuz" > /dev/null; then | |
76 | DEBUGINFOD=1 | |
77 | ls -ald `debuginfod-find debuginfo "$vmlinuz"` | |
78 | echo "Download successful. Assuming debuginfod server usage." | |
79 | else | |
80 | echo "Download failed." | |
81 | fi | |
82 | else | |
83 | echo 'Suggestion: consider configuring automatic debuginfo downloading via debuginfod.' | |
84 | fi | |
85 | } | |
86 | ||
87 | ||
88 | prep_rpm_based() { | |
89 | # uname -r can produce different kinds of output: | |
90 | # 2.6.32-30.el6.x86_64 (no variant, but including ".arch") | |
91 | # 2.6.18-194.3.1.el5debug ("variant", without dot, no arch) | |
92 | # 2.6.33.4-95.fc13.i686.PAE (".arch.variant", two dots) | |
93 | # 3.18.6-100.fc20.i686+PAE (".arch+variant", dot, plus) | |
94 | KERNEL="kernel" | |
95 | for VARIANT in debug kdump PAE xen; do | |
96 | # strip out ".variant" or else "+variant" or else "variant" at end. | |
97 | TMP=`echo $UNAME | sed "s/[\.\+]\?$VARIANT\$//"` | |
98 | if [ "$TMP" != "$UNAME" ]; then | |
99 | UNAME=$TMP; KERNEL="kernel-$VARIANT" | |
100 | fi | |
101 | done | |
102 | # and then we have rhel9 era kernel-rt's: | |
103 | # 5.14.0-200.rt14.201.el9 -> | |
104 | # "kernel-rt-debug-5.14.0-200.rt14.201.el9" | |
105 | # OR?! "kernel-rt-5.14.0-200.rt14.201.el9" | |
106 | # OR??!"kernel-rt-5.14.0-447.el9.x86_64+rt" | |
107 | if expr "$UNAME" : ".*\.rt.*" || expr "$UNAME" : ".*\+rt.*" >/dev/null; | |
108 | then | |
109 | KERNEL=`echo $KERNEL | sed -e s,kernel,kernel-rt,` | |
110 | fi | |
111 | ||
112 | KERN_ARCH=`uname -m` | |
113 | # strip arch from uname, for kernels like 5.14.0-447.el9.x86_64+rt or | |
114 | # 6.9.0-0.rc2.1.el10.x86_64+rt strip the +rt suffix too | |
115 | KERN_REV=`echo $UNAME | sed s/.$KERN_ARCH// | sed s/\+rt$//` | |
116 | if [ -x /usr/bin/dnf4 ]; then | |
117 | DI="dnf4 debuginfo-install" | |
118 | DI_DEPS="" | |
119 | D="dnf4" | |
120 | elif [ -x /usr/bin/dnf-3 ]; then | |
121 | DI="dnf-3 debuginfo-install" | |
122 | DI_DEPS="" | |
123 | D="dnf-3" | |
124 | elif [ -x /usr/bin/dnf ]; then | |
125 | DI="dnf debuginfo-install" | |
126 | DI_DEPS="" | |
127 | D="dnf" | |
128 | else | |
129 | DI="debuginfo-install" | |
130 | DI_DEPS="yum-utils" | |
131 | D="yum" | |
132 | fi | |
133 | if test "$bequiet" = "true"; then | |
134 | DI="$DI --quiet" | |
135 | D="$D --quiet" | |
136 | fi | |
137 | CANDIDATES="$KERNEL-$KERN_REV.$KERN_ARCH \ | |
138 | $KERNEL-devel-$KERN_REV.$KERN_ARCH \ | |
139 | $DI_DEPS" | |
140 | if [ "$DEBUGINFOD" -eq 0 ]; then # add debuginfo search if not already | |
141 | CANDIDATES="$CANDIDATES $KERNEL-debuginfo-$KERN_REV.$KERN_ARCH" | |
142 | fi | |
143 | NEEDED=`rpm --qf "%{name}-%{version}-%{release}.%{arch}\n" \ | |
144 | -q $CANDIDATES | grep "is not installed" | awk '{print $2}'` | |
145 | if [ "$NEEDED" != "" ]; then | |
146 | echo -e "Need to install the following packages:\n$NEEDED" | |
147 | if [ `id -u` = "0" ]; then #attempt to install | |
148 | $D install -y --enablerepo=\* $NEEDED | |
149 | if expr "$NEEDED" : ".*debuginfo.*" >/dev/null; | |
150 | then | |
151 | $DI -y $KERNEL-$KERN_REV.$KERN_ARCH; | |
152 | fi | |
153 | rpm -q $NEEDED | |
154 | rc=$? | |
155 | check_error $rc "problem installing rpm(s) $NEEDED\nin case of file conflicts, try again after # $D erase $KERNEL-debuginfo" | |
156 | fi | |
157 | fi | |
158 | } | |
159 | ||
160 | ||
161 | ||
162 | prep_deb_based() { | |
163 | if [ $# -ne 0 ]; then | |
164 | echo "Specifying kernel version is not yet support on deb based systems." 1>&2 | |
165 | exit 1 | |
166 | fi | |
167 | ||
168 | # 2.6.32-5-amd64 | |
169 | # 2.6.32-37-generic | |
170 | ABINAME="$(cut -d " " -f 3 /proc/version)" | |
171 | ||
172 | # 2.6.32 | |
173 | BASEVERSION="$(echo "$ABINAME" | cut -d "-" -f 1)" | |
174 | DEBIAN_FRONTEND=noninteractive # don't confirm or chat | |
175 | export DEBIAN_FRONTEND | |
176 | ||
177 | case "$DISTRO" in | |
178 | Debian) # 2.6.32-39 | |
179 | if uname -v | grep -q Debian; then | |
180 | VERSION="$(uname -v | cut -d " " -f 4)" | |
181 | else | |
182 | VERSION="$(cut -d " " -f 3 /proc/version)" | |
183 | fi | |
184 | ;; | |
185 | Ubuntu) | |
186 | # 2.6.32-37.81 | |
187 | if [ -f /proc/version_signature ]; then | |
188 | VERSION="$(cut -d " " -f 2 /proc/version_signature | cut -d "-" -f 1-2)" | |
189 | else # 4.18 | |
190 | VERSION="$(cut -d " " -f 3 /proc/version)" | |
191 | fi | |
192 | ;; | |
193 | esac | |
194 | ||
195 | ( | |
196 | echo "make >= 0" | |
197 | echo "linux-image-$ABINAME = $VERSION" | |
198 | echo "linux-headers-$ABINAME = $VERSION" | |
199 | if [ "$DEBUGINFOD" -eq 0 ]; then # add dbgsym search if not already | |
200 | echo "linux-image-$ABINAME-dbgsym = $VERSION" | |
201 | fi | |
202 | ) | while read package relation requiredversion; do | |
203 | installedversion="$(dpkg-query -W "$package" 2> /dev/null | cut -f 2)" | |
204 | if [ "$installedversion" = "" ]; then | |
205 | availableversion="$(apt-cache show $package 2> /dev/null | grep ^Version: | cut -d " " -f 2)" | |
206 | if [ "$availableversion" = "" -a "$(echo $package | grep dbgsym$)" ]; then | |
207 | echo "You need package $package but it does not seem to be available" | |
208 | if [ "$DISTRO" = "Ubuntu" ]; then | |
209 | echo " Ubuntu -dbgsym packages are typically in a separate repository" | |
210 | echo " Follow https://wiki.ubuntu.com/DebuggingProgramCrash to add this repository" | |
211 | elif [ "$DISTRO" = "Debian" ]; then | |
212 | echo " Debian -dbgsym packages are typically in a separate repository" | |
213 | echo " Follow https://wiki.debian.org/AutomaticDebugPackages to add this repository" | |
214 | fi | |
215 | else | |
216 | echo "Need to install $package" | |
217 | if [ `id -u` = "0" ]; then #attempt to install | |
218 | q=""; test "$bequiet" = "true" && q='--quiet' | |
219 | apt-get $q -y install $package | |
220 | fi | |
221 | fi | |
222 | elif ! dpkg --compare-versions $installedversion $relation $requiredversion; then | |
223 | echo "Package $package version $installedversion does not match version of currently running kernel: $requiredversion" | |
224 | echo " Consider apt-get upgrade && reboot" | |
225 | fi | |
226 | done | |
227 | ||
228 | user="$(id --user --name)" | |
229 | if [ "$user" != "root" ]; then | |
230 | groups="$(id --groups --name)" | |
231 | for i in stapusr stapdev; do | |
232 | if [ "$(echo $groups | grep $i)" = "" ]; then | |
233 | echo "Be root or adduser $user $i" | |
234 | fi | |
235 | done | |
236 | fi | |
237 | } | |
238 | ||
239 | ||
240 | prep_debuginfod "$@" | |
241 | DISTRO="$(lsb_release --id --short 2> /dev/null)" | |
242 | case "$DISTRO" in | |
243 | Debian|Ubuntu) | |
244 | prep_deb_based "$@" | |
245 | ;; | |
246 | *) | |
247 | prep_rpm_based "$@" | |
248 | ;; | |
249 | esac |