#!/usr/bin/bash 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 'Debuginfo automatic downloading is not configured via $DEBUGINFOD_URLS' 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 KERN_ARCH=`uname -m` KERN_REV=`echo $UNAME | sed s/.$KERN_ARCH//` # strip arch from uname if [ -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 | cut -d " " -f 4)" 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 echo "linux-image-$ABINAME-dbgsym = $VERSION" 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