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 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250
|
#! /bin/bash
# This file is part of systemtap, and is free software. You can
# redistribute it and/or modify it under the terms of the GNU General
# Public License (GPL); either version 2, or (at your option) any
# later version.
LANG=C; export LANG
PATH=/usr/sbin:/sbin:/usr/bin:/bin:$PATH; export PATH
check_error() { if test $1 != 0; then printf "\n$2\n"; exit $1; fi }
help()
{
cat <<'EOF'
Usage: stap-prep [OPTION]... [custom_uname]
prepare system for systemtap use
Options:
[-q|--quiet]
[-h|--help]
[custom_uname]
EOF
}
UNAME=`uname -r` # determine the kernel running on the machine
# Suppress verbose output and progress indicators
bequiet=false
while [ $# -gt 0 ]; do
case "$1" in
-q|--quiet)
bequiet=true
;;
-h|--help)
help
done=true
;;
*)
UNAME=$1
shift
break
;;
esac
shift
done
# help given
if [ "$done" = "true" ]; then exit 0; fi
UNAME=`echo $UNAME | sed "s/ //"` #strip out any whitespace
echo "Configuring for kernel release $UNAME"
# See if the configured debuginfod
DEBUGINFOD=0
prep_debuginfod() {
# Choose a representative part - the vmlinuz file itself, which
# may be compressed-ELF or something else. Previously, used a
# vdso* image only, but that false-positive tricks stap-prep on
# aarch64/s390x, due to rhbz 1891509 / elfutils PR25498
vmlinuz=/lib/modules/$UNAME/vmlinuz
if [ -n "$DEBUGINFOD_URLS" ]; then
echo "Please wait, attempting to download $vmlinuz debuginfo"
if [ -z "$DEBUGINFOD_TIMEOUT" ]; then
DEBUGINFOD_TIMEOUT=300
export DEBUGINFOD_TIMEOUT
echo "Increasing DEBUGINFOD_TIMEOUT to $DEBUGINFOD_TIMEOUT temporarily"
fi
DEBUGINFOD_PROGRESS=1
export DEBUGINFOD_PROGRESS
if debuginfod-find debuginfo "$vmlinuz" > /dev/null; then
DEBUGINFOD=1
ls -ald `debuginfod-find debuginfo "$vmlinuz"`
echo "Download successful. Assuming debuginfod server usage."
else
echo "Download failed."
fi
else
echo 'Suggestion: consider configuring automatic debuginfo downloading via debuginfod.'
fi
}
prep_rpm_based() {
# uname -r can produce different kinds of output:
# 2.6.32-30.el6.x86_64 (no variant, but including ".arch")
# 2.6.18-194.3.1.el5debug ("variant", without dot, no arch)
# 2.6.33.4-95.fc13.i686.PAE (".arch.variant", two dots)
# 3.18.6-100.fc20.i686+PAE (".arch+variant", dot, plus)
KERNEL="kernel"
for VARIANT in debug kdump PAE xen; do
# strip out ".variant" or else "+variant" or else "variant" at end.
TMP=`echo $UNAME | sed "s/[\.\+]\?$VARIANT\$//"`
if [ "$TMP" != "$UNAME" ]; then
UNAME=$TMP; KERNEL="kernel-$VARIANT"
fi
done
# and then we have rhel9 era kernel-rt's:
# 5.14.0-200.rt14.201.el9 ->
# "kernel-rt-debug-5.14.0-200.rt14.201.el9"
# OR?! "kernel-rt-5.14.0-200.rt14.201.el9"
if expr "$UNAME" : ".*\.rt.*" >/dev/null;
then
KERNEL=`echo $KERNEL | sed -e s,kernel,kernel-rt,`
fi
KERN_ARCH=`uname -m`
KERN_REV=`echo $UNAME | sed s/.$KERN_ARCH//` # strip arch from uname
if [ -x /usr/bin/dnf4 ]; then
DI="dnf4 debuginfo-install"
DI_DEPS=""
D="dnf4"
elif [ -x /usr/bin/dnf-3 ]; then
DI="dnf-3 debuginfo-install"
DI_DEPS=""
D="dnf-3"
elif [ -x /usr/bin/dnf ]; then
DI="dnf debuginfo-install"
DI_DEPS=""
D="dnf"
else
DI="debuginfo-install"
DI_DEPS="yum-utils"
D="yum"
fi
if test "$bequiet" = "true"; then
DI="$DI --quiet"
D="$D --quiet"
fi
CANDIDATES="$KERNEL-$KERN_REV.$KERN_ARCH \
$KERNEL-devel-$KERN_REV.$KERN_ARCH \
$DI_DEPS"
if [ "$DEBUGINFOD" -eq 0 ]; then # add debuginfo search if not already
CANDIDATES="$CANDIDATES $KERNEL-debuginfo-$KERN_REV.$KERN_ARCH"
fi
NEEDED=`rpm --qf "%{name}-%{version}-%{release}.%{arch}\n" \
-q $CANDIDATES | grep "is not installed" | awk '{print $2}'`
if [ "$NEEDED" != "" ]; then
echo -e "Need to install the following packages:\n$NEEDED"
if [ `id -u` = "0" ]; then #attempt to install
$D install -y --enablerepo=\* $NEEDED
if expr "$NEEDED" : ".*debuginfo.*" >/dev/null;
then
$DI -y $KERNEL-$KERN_REV.$KERN_ARCH;
fi
rpm -q $NEEDED
rc=$?
check_error $rc "problem installing rpm(s) $NEEDED\nin case of file conflicts, try again after # $D erase $KERNEL-debuginfo"
fi
fi
}
prep_deb_based() {
if [ $# -ne 0 ]; then
echo "Specifying kernel version is not yet support on deb based systems." 1>&2
exit 1
fi
# 2.6.32-5-amd64
# 2.6.32-37-generic
ABINAME="$(cut -d " " -f 3 /proc/version)"
# 2.6.32
BASEVERSION="$(echo "$ABINAME" | cut -d "-" -f 1)"
DEBIAN_FRONTEND=noninteractive # don't confirm or chat
export DEBIAN_FRONTEND
case "$DISTRO" in
Debian) # 2.6.32-39
if uname -v | grep -q Debian; then
VERSION="$(uname -v | grep -oE 'Debian ([0-9\.-]+)' | sed 's/Debian //')"
else
VERSION="$(cut -d " " -f 3 /proc/version)"
fi
;;
Ubuntu)
# 2.6.32-37.81
if [ -f /proc/version_signature ]; then
VERSION="$(cut -d " " -f 2 /proc/version_signature | cut -d "-" -f 1-2)"
else # 4.18
VERSION="$(cut -d " " -f 3 /proc/version)"
fi
;;
esac
(
echo "make >= 0"
echo "linux-image-$ABINAME = $VERSION"
echo "linux-headers-$ABINAME = $VERSION"
if [ "$DEBUGINFOD" -eq 0 ]; then # add dbgsym search if not already
if [ "$DISTRO" = "Debian" ]; then
echo "linux-image-$ABINAME-dbg = $VERSION"
else
echo "linux-image-$ABINAME-dbgsym = $VERSION"
fi
fi
) | while read package relation requiredversion; do
installedversion="$(dpkg-query -W "$package" 2> /dev/null | cut -f 2)"
if [ "$installedversion" = "" ]; then
availableversion="$(apt-cache show $package 2> /dev/null | grep ^Version: | cut -d " " -f 2)"
if [ "$availableversion" = "" -a "$(echo $package | grep dbgsym$)" ]; then
echo "You need package $package but it does not seem to be available"
if [ "$DISTRO" = "Ubuntu" ]; then
echo " Ubuntu -dbgsym packages are typically in a separate repository"
echo " Follow https://wiki.ubuntu.com/DebuggingProgramCrash to add this repository"
elif [ "$DISTRO" = "Debian" ]; then
echo " Debian -dbgsym packages are typically in a separate repository"
echo " Follow https://wiki.debian.org/AutomaticDebugPackages to add this repository"
fi
else
echo "Need to install $package"
if [ `id -u` = "0" ]; then #attempt to install
q=""; test "$bequiet" = "true" && q='--quiet'
apt-get $q -y install $package
fi
fi
elif ! dpkg --compare-versions $installedversion $relation $requiredversion; then
echo "Package $package version $installedversion does not match version of currently running kernel: $requiredversion"
echo " Consider apt-get upgrade && reboot"
fi
done
user="$(id --user --name)"
if [ "$user" != "root" ]; then
groups="$(id --groups --name)"
for i in stapusr stapdev; do
if [ "$(echo $groups | grep $i)" = "" ]; then
echo "Be root or adduser $user $i"
fi
done
fi
}
prep_debuginfod "$@"
DISTRO="$(lsb_release --id --short 2> /dev/null)"
case "$DISTRO" in
Debian|Ubuntu)
prep_deb_based "$@"
;;
*)
prep_rpm_based "$@"
;;
esac
|