diff options
| author | Linus Torvalds <torvalds@linux-foundation.org> | 2026-08-30 09:22:00 -0700 |
|---|---|---|
| committer | Linus Torvalds <torvalds@linux-foundation.org> | 2026-08-30 09:22:00 -0700 |
| commit | 034dd340b08be1f2f0477ad16131d609f9dbd53c (patch) | |
| tree | 2536f4b2d7893ccd916b5abdf3c454ad6edc03c2 /tools/perf/scripts/install-build-deps.sh | |
| download | linux-stable-034dd340b08be1f2f0477ad16131d609f9dbd53c.tar.gz linux-stable-034dd340b08be1f2f0477ad16131d609f9dbd53c.zip | |
Merge tag 'trace-v7.3-2' of git://git.kernel.org/pub/scm/linux/kernel/git/trace/linux-tracegrafted
Pull tracing fixes from Steven Rostedt:
- Fix error output of boot instance creation failure
Currently if a boot instance creation fails, instead of printing out
the name of the instance that failed, it prints "(null)". That is
because it prints "cur_str" that had already been processed by
strsep(). Print the saved name instead.
While at it, print the error code of the failure.
- Fix use-after-free for same named historgrams
Histograms can be named so that they can be used in multiple events.
But if the named histogram has a variable attached, the second event
that uses the named histogram which duplicates it and needs to free
the original after duplication leaves the old variable in place and
still visible. If another histogram uses than variable, it will use
the stale one which will try to reference the freed duplicate
histogram and crash the kernel.
Free the duplicate variables along with the duplicated histogram
data.
- Check return value of kthread_run() in event self test
The events self tests uses a kthread for testing but does not check
if it succeeded in creating a kthread. If the kthread creation were
to fail, the code will still try to call kthread_stop() on the error
returned.
- Fix race between reading trace_pipe and updating subbuffer size
If a user is reading the trace_pipe file at the same time they update
the ring buffer sub-buffer size, can cause the trace_pipe read to
read stale data. Add trace_access_lock() around updating the ring
buffer sub-buffer size.
- Fix eventfs_inode on failure path in creation of the events directory
In the creation of the "events" directory, if after allocating the
eventfs_inode a failure is detected, it calls cleanup_ei() which
calls free_ei(). The free_ei() will test if eventfs_inode being freed
has no children. It is a bug if it does. But on the failure case of
the creation of the "events" directory, the children lists have not
yet been initialized and the free will trigger a warning because
list_empty() on an uninitialized list returns false.
Move the initialization into init_ei() where it makes more sense and
makes sure that a created eventfs_inode has its lists initialized
upon creation.
- Check return value of kthread_run() in ftrace direct sample code
The sample code that shows how to use the ftrace direct calls does
not test the return of kthread_run() to see if it succeeds. Return a
failure if the kthread_run() doesn't succeed.
- Clear user events state on fork in case of alloc failure
On fork, the child gets a pointer to the parent's user events state.
It makes a copy of it then updates the child's pointer to it. But if
the allocation fails, the duplication function leaves the child with
a pointer to its parent's descriptor. When the child cleans up its
data, it will free the parent's descriptor while the parent is still
using it.
In the duplication function, set the child's user_event_mm to NULL
before testing if the allocation succeeded, and when it exits it will
not free the parent's descriptor.
- Fix retry exhaustion in simple ring buffer reader swap
simple_ring_buffer_swap_reader_page() starts with retry set to 8 and
post-decrements it only after a failed link replacement. On the final
attempt, a successful replacement leaves retry at zero, while a
failed replacement leaves it at -1.
But the check for success expects the retry value to be non-zero and
exits with an error on zero. This is the opposite result. Fix it.
- Fail nicely when the remote swap_reader_page() returns an error
Currently, if the swap_reader_page() of a remote buffer fails, it
triggers a WARN_ON_ONCE() and continues normally. Instead, have it
exit with an error and a pr_warn() print instead of a full WARNING.
* tag 'trace-v7.3-2' of git://git.kernel.org/pub/scm/linux/kernel/git/trace/linux-trace:
ring-buffer: Stop remote reader update when page swap fails
tracing: Fix retry exhaustion in simple ring buffer reader swap
tracing/user_events: Clear copied tracing state before fork duplication
samples/ftrace: Fix kthread_stop() on ERR_PTR in ftrace-direct-multi-modify
samples/ftrace: Fix kthread_stop() on ERR_PTR in ftrace-direct-modify
eventfs: Initialize ei->children and ei->list in init_ei()
tracing: Fix use-after-free in trace_pipe read on sub-buffer order change
tracing: Fix crash passing ERR_PTR to kthread_stop()
tracing: Fix use-after-free with same-name named triggers
tracing: Fix logged instance name on creation failure
Diffstat (limited to 'tools/perf/scripts/install-build-deps.sh')
| -rwxr-xr-x | tools/perf/scripts/install-build-deps.sh | 603 |
1 files changed, 603 insertions, 0 deletions
diff --git a/tools/perf/scripts/install-build-deps.sh b/tools/perf/scripts/install-build-deps.sh new file mode 100755 index 000000000..d003e7fab --- /dev/null +++ b/tools/perf/scripts/install-build-deps.sh @@ -0,0 +1,603 @@ +#!/bin/bash +# SPDX-License-Identifier: GPL-2.0 +# +# No 'set -e': the script uses explicit checks for its error paths, and +# is also run via '$(SHELL) .../install-build-deps.sh' from the make +# target in tools/perf/Makefile.perf, where a shebang option would be +# ignored anyway, so direct and make-driven runs behave the same. +# +# Install the development packages needed to build tools/perf. +# +# The package set is derived from the feature tests in tools/build/feature/: +# each feature test that perf may compile is mapped to the devel package +# that provides the headers/libraries it checks, so that a subsequent +# 'make -C tools/perf' build enables the corresponding perf features. +# +# Currently supported distros, each validated in a fresh container: +# +# - Fedora, on dnf, validated on Fedora 44, in a toolbx container: +# +# toolbox create fedora:44 +# toolbox enter fedora:44 +# +# - Ubuntu, on apt-get, validated on Ubuntu 26.04, in a distrobox +# container: +# +# distrobox create --image ubuntu:26.04 +# distrobox enter ubuntu-26-04 +# +# The apt-get install runs with a noninteractive debconf frontend: +# default-jdk, needed by the jvmti feature tests, pulls in tzdata, +# which prompts for the timezone on a terminal and would block the +# install, e.g. in a container shared with an interactive session. +# +# - Debian, on apt-get, reusing the Ubuntu mapping, validated on +# Debian 13 (trixie), in a distrobox container: +# +# distrobox create --image debian:trixie +# distrobox enter debian-trixie +# +# - RHEL and its variants (RHEL, CentOS Stream, Rocky Linux, AlmaLinux, +# Oracle Linux), on dnf (RHEL 8 and later), validated on CentOS +# Stream 10, in a distrobox container: +# +# distrobox create --image quay.io/centos/centos:stream10 +# distrobox enter centos-stream10 +# +# The RHEL family reuses most Fedora package names, with these +# differences, handled by probing the enabled repos: +# +# - zlib.h comes from zlib-ng-compat-devel on the RHEL 10 family, +# zlib-devel on RHEL 9 and earlier; +# - the JDK devel package is versioned, there is no +# java-latest-openjdk-devel: java-21-openjdk-devel on the RHEL +# 10 family, java-17-openjdk-devel on RHEL 9, java-11-openjdk- +# devel on RHEL 8; +# - libbpf-devel and capstone-devel are in the CRB repo on RHEL +# and CentOS Stream 10 ('dnf config-manager --set-enabled crb') +# and in EPEL on RHEL 9 and earlier; +# - libbabeltrace2-devel is not packaged on the RHEL 10 family. +# +# On the RHEL family, packages not available on the enabled repos +# are skipped and listed at the end of the run, so that a distro +# with CRB/EPEL enabled gets the full set, and a distro without +# them still installs what it can. +# +# Running inside a container keeps the host system unmodified. +# +# Usage: install-build-deps.sh [OPTIONS] +# +# Options: +# --list list the packages that would be installed, then exit +# --dry-run show the install command that would be run, without +# running it +# --distro ID force a distro: fedora, rhel, ubuntu, debian +# (default: auto-detect) +# -h, --help print this help message +# +# Requires root (or passwordless sudo) to actually install packages. + +set -u + +DISTRO="" + +help() { + cat <<EOF +Usage: $(basename "$0") [--list] [--dry-run] [--distro ID] [-h|--help] + +Install the development packages needed to build tools/perf. + +The package set is derived from the feature tests in tools/build/feature/, +mapping each one with an external dependency to the devel package providing +it, so the corresponding feature gets enabled on a build. + +Options: + --list list the packages that would be installed, then exit + --dry-run show the install command that would be run, without running it + --distro ID force a distro: fedora, rhel, ubuntu, debian + -h, --help print this help message + +Distros supported: Fedora (dnf), validated in a toolbx container on +Fedora 44, Ubuntu (apt-get), validated in a distrobox container on +Ubuntu 26.04, Debian (apt-get), reusing the Ubuntu mapping, validated +in a distrobox container on Debian 13 (trixie), and the RHEL family +(dnf, RHEL 8 and later), validated on CentOS Stream 10 in a distrobox +container. On the RHEL family, packages not available on the enabled +repos are skipped and listed at the end; some there, e.g. +libbpf-devel and capstone-devel, come from the CRB repo on RHEL and +CentOS Stream 10 ('dnf config-manager --set-enabled crb') and from +EPEL on RHEL 9 and earlier. +EOF + exit 0 +} + +# --------------------------------------------------------------------- +# Return the Fedora package(s) providing the devel requirements of a +# feature test in tools/build/feature/. Multiple packages are separated +# by spaces; an empty result means the test has no external devel +# dependency (pure toolchain/glibc, or no equivalent Fedora package). +# +# The mapping was built by checking, for each feature test, which Fedora +# devel package provides the headers the test compiles against. +# --------------------------------------------------------------------- +fedora_pkg_for() { + local feat="$1" + case "$feat" in + libelf|libelf-getphdrnum|libelf-gelf_getnote|libelf-getshdrstrndx) + echo "elfutils-libelf-devel" + ;; + libelf-zstd) + echo "elfutils-libelf-devel libzstd-devel" + ;; + libdw) + echo "elfutils-devel" + ;; + # test-libdebuginfod.c includes <elfutils/debuginfod.h>, which is + # provided by elfutils-debuginfod-client-devel, not elfutils-devel. + libdebuginfod) + echo "elfutils-debuginfod-client-devel" + ;; + libnuma|numa_num_possible_cpus) + echo "numactl-devel" + ;; + libzstd) + echo "libzstd-devel" + ;; + zlib) + echo "zlib-devel" + ;; + lzma) + echo "xz-devel" + ;; + libslang) + echo "slang-devel" + ;; + libcapstone) + echo "capstone-devel" + ;; + libpython) + echo "python3-devel" + ;; + libtraceevent) + echo "libtraceevent-devel" + ;; + cxa-demangle) + echo "libstdc++-devel" + ;; + libbpf) + echo "libbpf-devel" + ;; + babeltrace2-ctf-writer) + echo "libbabeltrace2-devel" + ;; + libopenssl) + echo "openssl-devel" + ;; + libpfm4) + echo "libpfm-devel" + ;; + sdt) + echo "systemtap-sdt-devel" + ;; + clang-bpf-co-re) + echo "clang-devel" + ;; + llvm|llvm-perf) + echo "llvm-devel" + ;; + jvmti|jvmti-cmlr) + echo "java-latest-openjdk-devel" + ;; + esac + # Pure toolchain/libc features (backtrace, eventfd, fortify-source, + # gettid, glibc, hello, reallocarray, pthread-*, stackprotector-all, + # timerfd, scandirat, sched_getcpu, setns, file-handle, + # bionic...) need no external package: their + # requirements are covered by the base packages below. Features that + # perf's own build does not check (libcap, libcheck, libcpupower, + # libtracefs, whose feature tests exist for rtla/bpftool/rv) and the + # opt-in features, which a default build does not enable: the libbfd + # disassembler family (libbfd, libbfd-threadsafe, libbfd-liberty, + # disassembler-*, cplus-demangle), only linked on BUILD_NONDISTRO + # builds and deprecated in favor of capstone, GTK2, LIBPERL and + # LIBUNWIND support (ifdef GTK2 / ifdef LIBPERL / LIBUNWIND=1), + # and CoreSight (ifdef CORESIGHT), are deliberately not mapped. + # libaio is not mapped either: its + # test uses the POSIX AIO API (aio.h, aio_*, -lrt), provided by + # glibc headers (pulled in by the libc headers package) in the + # base set, not the native libaio.h/io_submit API that + # libaio-devel provides. +} + +# --------------------------------------------------------------------- +# Check whether the first argument is provided by the enabled repos, or +# is already installed, returning 0 if so and printing nothing. +# +# dnf repoquery exits 0 even when the pattern does not match anything, +# so availability is judged by the output being non-empty, not by the +# exit code. +# --------------------------------------------------------------------- +pkg_available() { + local p out + for p in "$@"; do + out=$(dnf repoquery --quiet --available "$p" 2>/dev/null) + [ -n "$out" ] || out=$(dnf repoquery --quiet --installed "$p" 2>/dev/null) + [ -n "$out" ] && return 0 + done + return 1 +} + +# --------------------------------------------------------------------- +# Return the first of its arguments that pkg_available() accepts. +# --------------------------------------------------------------------- +pick_available() { + local p + for p in "$@"; do + if pkg_available "$p"; then + echo "$p" + return 0 + fi + done + return 1 +} + +# --------------------------------------------------------------------- +# Return the RHEL-family package(s) providing the devel requirements of +# a feature test. This family reuses the Fedora mapping, whose names +# apply to it as well, except for the features whose Fedora package +# does not exist there, kept in the case below. +# +# Whether the resulting package is actually installable is checked in +# package_set(), as some of these names live in the CRB or EPEL repos, +# which may not be enabled: on the RHEL 10 family libbpf-devel and +# capstone-devel come from CRB, and libbabeltrace2-devel is not +# packaged at all. +# --------------------------------------------------------------------- +rhel_pkg_for() { + local feat="$1" + case "$feat" in + zlib) + # zlib-ng-compat-devel on the RHEL 10 family, zlib-devel on + # RHEL 9 and earlier. If neither is on the enabled repos, + # fall back to the first candidate so that package_set() + # reports it as missing instead of silently dropping the + # feature from the end-of-run note. + pick_available zlib-devel zlib-ng-compat-devel || echo "zlib-devel" + ;; + jvmti|jvmti-cmlr) + # No java-latest-openjdk-devel on the RHEL family: the JDK + # devel package is versioned per release. + pick_available java-latest-openjdk-devel java-21-openjdk-devel java-17-openjdk-devel java-11-openjdk-devel || echo "java-latest-openjdk-devel" + ;; + *) + fedora_pkg_for "$feat" + ;; + esac +} + +# --------------------------------------------------------------------- +# Return the Debian/Ubuntu package(s) providing the devel requirements +# of a feature test in tools/build/feature/. This mapping is shared by +# Debian and Ubuntu, whose package names for these devel packages match, +# and is validated on Ubuntu 26.04 and Debian 13 (trixie). +# --------------------------------------------------------------------- +debian_pkg_for() { + local feat="$1" + case "$feat" in + libelf|libelf-getphdrnum|libelf-gelf_getnote|libelf-getshdrstrndx) + echo "libelf-dev" + ;; + libelf-zstd) + echo "libelf-dev libzstd-dev" + ;; + libdw) + echo "libdw-dev" + ;; + libdebuginfod) + echo "libdebuginfod-dev" + ;; + libnuma|numa_num_possible_cpus) + echo "libnuma-dev" + ;; + libzstd) + echo "libzstd-dev" + ;; + zlib) + echo "zlib1g-dev" + ;; + lzma) + echo "liblzma-dev" + ;; + libslang) + echo "libslang2-dev" + ;; + libcapstone) + echo "libcapstone-dev" + ;; + libpython) + echo "python3-dev" + ;; + libtraceevent) + echo "libtraceevent-dev" + ;; + # The cxa-demangle feature test links against libstdc++ builtin + # demangling, so on Debian-derived distros it is covered by the + # g++ base package below, which pulls in libstdc++-*-dev. + cxa-demangle) + ;; + libbpf) + echo "libbpf-dev" + ;; + babeltrace2-ctf-writer) + echo "libbabeltrace2-dev" + ;; + libopenssl) + echo "libssl-dev" + ;; + libpfm4) + echo "libpfm4-dev" + ;; + sdt) + echo "systemtap-sdt-dev" + ;; + # test-clang-bpf-co-re.c invokes the clang binary (not libclang-cpp), + # so clang suffices; llvm-dev brings llvm-config, needed by the + # llvm/llvm-perf tests below. + clang-bpf-co-re) + echo "clang llvm-dev" + ;; + llvm|llvm-perf) + echo "llvm-dev" + ;; + jvmti|jvmti-cmlr) + echo "default-jdk" + ;; + esac + # Same rationale as in fedora_pkg_for() above for unmapped tests. +} + +# Base packages needed by any perf build, regardless of feature tests: +# compiler, libc headers, flex/bison for the parser, kernel headers +# for UAPI headers with no in-tree copy, e.g. <linux/capability.h>, and +# gcc-c++ (dnf) / g++ (apt) is needed by the C++-based feature tests +# (cxa-demangle, llvm, llvm-perf), compiled with $(CXX), and +# pulls in libstdc++-devel / libstdc++-*-dev. +# python3-setuptools is needed to build the python binding (perf's +# util/setup.py uses it; without it binding is skipped with a warning). +# rust is not a header-based feature test: test-rust.bin just checks +# "$(RUSTC) --version" (tools/build/feature/Makefile), so it is mapped +# here like the other toolchain packages. +fedora_base_pkgs="gcc gcc-c++ make flex bison glibc-devel kernel-headers python3-setuptools rust" +# pkg-config mirrors the pkgconf-pkg-config package that Fedora +# installs by default, needed by the babeltrace2 feature test and +# libopenssl's pkg-config checks. +debian_base_pkgs="gcc g++ make pkg-config flex bison libc6-dev linux-libc-dev python3-setuptools rustc" +# pkg-config: like Fedora, on pkgconf since Fedora 26 / RHEL 8, with +# 'pkgconfig' live only as a virtual Provides of the pkgconf-pkg-config +# subpackage. List it explicitly because, unlike Fedora, a minimal +# RHEL-family container may not have it preinstalled. +rhel_base_pkgs="gcc gcc-c++ make flex bison glibc-devel kernel-headers pkgconf-pkg-config python3-setuptools rust" + +# --------------------------------------------------------------------- +# Distro detection +# --------------------------------------------------------------------- +detect_distro() { + if [ -n "$DISTRO" ]; then + echo "$DISTRO" + return + fi + local id + id=$( . /etc/os-release 2>/dev/null && echo "${ID:-}" ) + case "$id" in + fedora) echo "fedora" ;; + rhel|centos|rocky|almalinux|ol) + # All share the Fedora package names (with the exceptions + # handled by rhel_pkg_for()) and dnf. + echo "rhel" ;; + ubuntu) echo "ubuntu" ;; + debian) echo "debian" ;; + *) echo "" ;; + esac +} + +# --------------------------------------------------------------------- +# Feature test enumeration: mirror of the tests checked during a build, +# from the actual test-*.c / test-*.cpp sources in tools/build/feature/. +# --------------------------------------------------------------------- +feature_tests() { + local srcdir="$1" + local f + for f in "$srcdir"/tools/build/feature/test-*.c "$srcdir"/tools/build/feature/test-*.cpp; do + [ -e "$f" ] || continue + basename "$f" | sed -e 's/^test-//' -e 's/\.c$//' -e 's/\.cpp$//' + done +} + +# --------------------------------------------------------------------- +# Assemble the unique package list. Since the full feature set is mapped +# unconditionally, this installs the complete devel environment; installing +# an already-present package is a no-op for both dnf and apt-get, making +# this idempotent. On the RHEL family, packages not available on the +# enabled repos are skipped and echoed on stderr, reported at the end of +# the run by the caller (package_set() runs in a subshell, so a variable +# would not survive it). +# --------------------------------------------------------------------- +package_set() { + local distro="$1" srcdir="$2" + local feat pkg pkgs base_pkgs missing_pkgs="" + case "$distro" in + fedora) pkgs="$fedora_base_pkgs" ;; + rhel) pkgs="$rhel_base_pkgs" ;; + ubuntu|debian) pkgs="$debian_base_pkgs" ;; + esac + + # The base set must be checked against the enabled repos as well: + # e.g. 'rust' is only shipped as the rust-toolset AppStream module + # on RHEL 8 and 9, where dnf would abort the whole transaction + # with "No match for argument: rust" instead of skipping it, so + # unavailable base packages are skipped and noted like the mapped + # ones below. + if [ "$distro" = "rhel" ]; then + base_pkgs="$pkgs" + pkgs="" + for pkg in $base_pkgs; do + if pkg_available "$pkg"; then + pkgs="$pkgs $pkg" + else + missing_pkgs="$missing_pkgs $pkg" + fi + done + fi + + for feat in $(feature_tests "$srcdir"); do + case "$distro" in + fedora) pkg=$(fedora_pkg_for "$feat") ;; + rhel) pkg=$(rhel_pkg_for "$feat") ;; + *) pkg=$(debian_pkg_for "$feat") ;; + esac + # An empty result means the feature test has no external devel + # dependency (see the unmapped list in fedora_pkg_for()), so + # there is nothing to install and nothing to report as missing: + # packages that are genuinely unavailable on the RHEL family + # surface through rhel_pkg_for() falling back to its first + # candidate, so that the pkg_available() check below catches + # them and adds them to missing_pkgs. + [ -n "$pkg" ] || continue + for pkg in $pkg; do + if [ "$distro" = "rhel" ] && ! pkg_available "$pkg"; then + missing_pkgs="$missing_pkgs $pkg" + continue + fi + case " $pkgs " in + *" $pkg "*) ;; + *) pkgs="$pkgs $pkg" ;; + esac + done + done + [ -n "$missing_pkgs" ] && echo "$missing_pkgs" >&2 + echo "$pkgs" +} + +# --------------------------------------------------------------------- +# Report the RHEL-family packages that were skipped because the enabled +# repos do not provide them. +# --------------------------------------------------------------------- +note_missing() { + [ -n "$1" ] || return 0 + echo "Note: these packages are not available on the enabled repos" >&2 + echo "and were not installed, so the features they enable will stay" >&2 + echo "off in a perf build:" >&2 + echo "$1" | tr ' ' '\n' | grep -v '^$' | sort -u | sed 's/^/ /' >&2 + echo >&2 +} + +# --------------------------------------------------------------------- +# The install command proper for each supported package manager, plus +# the command massaged for --dry-run. +# --------------------------------------------------------------------- +install_cmd() { + local distro="$1"; shift + case "$distro" in + fedora|rhel) + echo "dnf install -y $*" + ;; + ubuntu|debian) + # a fresh container has no package index, so update first; run + # with a noninteractive debconf frontend: default-jdk, used by + # the jvmti feature tests, pulls in tzdata, which prompts for + # the timezone on a terminal and would block the install. The + # env var prefix works with the 'sh -c' invocation below, and + # shows up in --dry-run. + echo "DEBIAN_FRONTEND=noninteractive apt-get update && DEBIAN_FRONTEND=noninteractive apt-get install -y $*" + ;; + esac +} + +main() { + local action="install" + # Package accumulation happens in package_set(), which, together + # with the *_pkg_for() helpers, declares the per-feature 'pkg' + # locals; main() holds no per-feature package state, just the + # distro-wide list assembled by package_set(). + local srcdir distro pkgs cmd missing_file missing_pkgs + + while [ $# -gt 0 ]; do + case "$1" in + --list) action="list"; shift ;; + --dry-run) action="dry-run"; shift ;; + --distro) + [ $# -ge 2 ] || { + echo "error: --distro requires an argument (fedora, rhel, ubuntu, debian)" >&2 + exit 1 + } + DISTRO="$2"; shift 2 ;; + -h|--help) help ;; + *) echo "error: unknown argument: $1" >&2; exit 1 ;; + esac + done + + srcdir=$(cd "$(dirname "$0")/../../.." && pwd) + distro=$(detect_distro) + case "$distro" in + fedora|rhel|ubuntu|debian) ;; + *) + echo "error: unsupported distro (got '$distro'); the package mapping is not validated on other distros." >&2 + echo "Supported and validated: Fedora 44 (toolbx container), Ubuntu 26.04 and Debian 13 (distrobox containers), and CentOS Stream 10 (distrobox container)." >&2 + exit 1 + ;; + esac + + # The RHEL family mapping probes the enabled repos with dnf + # repoquery and installs with dnf, so reject the yum-only members of + # the family (RHEL 7 and earlier, e.g. Oracle Linux 7) with a clear + # error instead of silently judging every package as unavailable. + if [ "$distro" = "rhel" ] && ! command -v dnf >/dev/null 2>&1; then + echo "error: dnf not found, the RHEL family package mapping requires dnf (RHEL 8 and later)." >&2 + exit 1 + fi + + missing_file=$(mktemp) || { + echo "error: cannot create a temporary file (mktemp failed)" >&2 + exit 1 + } + # package_set() runs in a subshell, doing dnf repoquery loops that + # may be interrupted: a Ctrl-C during those loops hits these traps, + # turning SIGINT/SIGTERM into an exit that triggers the EXIT trap, + # removing the temp file, so the script terminates instead of + # resuming after the interrupted command, leaving no file behind. + trap 'rm -f "$missing_file"' EXIT + trap 'exit 1' INT TERM + pkgs=$(package_set "$distro" "$srcdir" 2>"$missing_file") + missing_pkgs=$(cat "$missing_file") + rm -f "$missing_file" + trap - EXIT INT TERM + + case "$action" in + list) + echo "$pkgs" | tr ' ' '\n' | grep -v '^$' | sort + note_missing "$missing_pkgs" + exit 0 + ;; + dry-run) + install_cmd "$distro" $pkgs + note_missing "$missing_pkgs" + exit 0 + ;; + esac + + echo "The following packages will be installed to enable perf features:" + echo "$pkgs" | tr ' ' '\n' | grep -v '^$' | sort | sed 's/^/ /' + echo + cmd=$(install_cmd "$distro" $pkgs) + if [ "$(id -u)" -eq 0 ]; then + sh -c "$cmd" + else + sudo sh -c "$cmd" + fi || { + echo "error: the install command failed, see the output above" >&2 + exit 1 + } + note_missing "$missing_pkgs" +} + +main "$@" |
