Quellcodebibliothek Statistik Leitseite products/sources/formale Sprachen/C/Linux/tools/testing/selftests/bpf/   (Open Source Betriebssystem Version 6.17.9©)  Datei vom 24.10.2025 mit Größe 11 kB image not shown  

Quelle  vmtest.sh   Sprache: Shell

 
#!/bin/bash
# SPDX-License-Identifier: GPL-2.0

set -e

# This script currently only works for the following platforms,
# as it is based on the VM image used by the BPF CI, which is
# available only for these architectures. We can also specify
# the local rootfs image generated by the following script:
https://github.com/libbpf/ci/blob/main/rootfs/mkrootfs_debian.sh
PLATFORM="${PLATFORM:-$(uname -m)}"
case "${PLATFORM}" in
s390x)
 QEMU_BINARY=qemu-system-s390x
 QEMU_CONSOLE="ttyS1"
 HOST_FLAGS=(-smp 2 -enable-kvm)
 CROSS_FLAGS=(-smp 2)
 BZIMAGE="arch/s390/boot/vmlinux"
 ARCH="s390"
 ;;
x86_64)
 QEMU_BINARY=qemu-system-x86_64
 QEMU_CONSOLE="ttyS0,115200"
 HOST_FLAGS=(-cpu host -enable-kvm -smp 8)
 CROSS_FLAGS=(-smp 8)
 BZIMAGE="arch/x86/boot/bzImage"
 ARCH="x86"
 ;;
aarch64)
 QEMU_BINARY=qemu-system-aarch64
 QEMU_CONSOLE="ttyAMA0,115200"
 HOST_FLAGS=(-M virt,gic-version=3 -cpu host -enable-kvm -smp 8)
 CROSS_FLAGS=(-M virt,gic-version=3 -cpu cortex-a76 -smp 8)
 BZIMAGE="arch/arm64/boot/Image"
 ARCH="arm64"
 ;;
riscv64)
 # required qemu version v7.2.0+
 QEMU_BINARY=qemu-system-riscv64
 QEMU_CONSOLE="ttyS0,115200"
 HOST_FLAGS=(-M virt -cpu host -enable-kvm -smp 8)
 CROSS_FLAGS=(-M virt -cpu rv64,sscofpmf=true -smp 8)
 BZIMAGE="arch/riscv/boot/Image"
 ARCH="riscv"
 ;;
ppc64el)
 QEMU_BINARY=qemu-system-ppc64
 QEMU_CONSOLE="hvc0"
 # KVM could not be tested for powerpc, therefore not enabled for now.
 HOST_FLAGS=(-machine pseries -cpu POWER9)
 CROSS_FLAGS=(-machine pseries -cpu POWER9)
 BZIMAGE="vmlinux"
 ARCH="powerpc"
 ;;
*)
 echo "Unsupported architecture"
 exit 1
 ;;
esac
DEFAULT_COMMAND="./test_progs"
MOUNT_DIR="mnt"
LOCAL_ROOTFS_IMAGE=""
ROOTFS_IMAGE="root.img"
OUTPUT_DIR="$HOME/.bpf_selftests"
KCONFIG_REL_PATHS=("tools/testing/selftests/bpf/config"
 "tools/testing/selftests/bpf/config.vm"
 "tools/testing/selftests/bpf/config.${PLATFORM}")
INDEX_URL="https://raw.githubusercontent.com/libbpf/ci/master/INDEX"
NUM_COMPILE_JOBS="$(nproc)"
LOG_FILE_BASE="$(date +"bpf_selftests.%Y-%m-%d_%H-%M-%S")"
LOG_FILE="${LOG_FILE_BASE}.log"
EXIT_STATUS_FILE="${LOG_FILE_BASE}.exit_status"

usage()
{
 cat <<EOF
Usage: $0 [-i] [-s] [-d <output_dir>] -- [<command>]

<command> is the command you would normally run when you are in
tools/testing/selftests/bpf. e.g:

 $0 -- ./test_progs -t test_lsm

If no command is specified and a debug shell (-s) is not requested,
"${DEFAULT_COMMAND}" will be run by default.

Using PLATFORM= and CROSS_COMPILE= options will enable cross platform testing:

  PLATFORM=<platform> CROSS_COMPILE=<toolchain> $0 -- ./test_progs -t test_lsm

If you build your kernel using KBUILD_OUTPUT= or O= options, these
can be passed as environment variables to the script:

  O=<kernel_build_path> $0 -- ./test_progs -t test_lsm

or

  KBUILD_OUTPUT=<kernel_build_path> $0 -- ./test_progs -t test_lsm

Options:

 -l)             Specify the path to the local rootfs image.
 -i)  Update the rootfs image with a newer version.
 -d)  Update the output directory (default: ${OUTPUT_DIR})
 -j)  Number of jobs for compilation, similar to -j in make
   (default: ${NUM_COMPILE_JOBS})
 -s)  Instead of powering off the VM, start an interactive
   shell. If <command> is specified, the shell runs after
   the command finishes executing
EOF
}

unset URLS
populate_url_map()
{
 if ! declare -p URLS &> /dev/null; then
  # URLS contain the mapping from file names to URLs where
  # those files can be downloaded from.
  declare -gA URLS
  while IFS=$'\t' read -r name url; do
   URLS["$name"]="$url"
  done < <(curl -Lsf ${INDEX_URL})
 fi
}

newest_rootfs_version()
{
 {
 for file in "${!URLS[@]}"do
  if [[ $file =~ ^"${PLATFORM}"/libbpf-vmtest-rootfs-(.*)\.tar\.zst$ ]]; then
   echo "${BASH_REMATCH[1]}"
  fi
 done
 } | sort -rV | head -1
}

download_rootfs()
{
 populate_url_map

 local rootfsversion="$(newest_rootfs_version)"
 local file="${PLATFORM}/libbpf-vmtest-rootfs-$rootfsversion.tar.zst"

 if [[ ! -v URLS[$file] ]]; then
  echo "$file not found" >&2
  return 1
 fi

 echo "Downloading $file..." >&2
 curl -Lsf "${URLS[$file]}" "${@:2}"
}

load_rootfs()
{
 local dir="$1"

 if ! which zstd &> /dev/null; then
  echo 'Could not find "zstd" on the system, please install zstd'
  exit 1
 fi

 if [[ -n "${LOCAL_ROOTFS_IMAGE}" ]]; then
  cat "${LOCAL_ROOTFS_IMAGE}" | zstd -d | sudo tar -C "$dir" -x
 else
  download_rootfs | zstd -d | sudo tar -C "$dir" -x
 fi
}

recompile_kernel()
{
 local kernel_checkout="$1"
 local make_command="$2"

 cd "${kernel_checkout}"

 ${make_command} olddefconfig
 ${make_command}
}

mount_image()
{
 local rootfs_img="${OUTPUT_DIR}/${ROOTFS_IMAGE}"
 local mount_dir="${OUTPUT_DIR}/${MOUNT_DIR}"

 sudo mount -o loop "${rootfs_img}" "${mount_dir}"
}

unmount_image()
{
 local mount_dir="${OUTPUT_DIR}/${MOUNT_DIR}"

 sudo umount "${mount_dir}" &> /dev/null
}

update_selftests()
{
 local kernel_checkout="$1"
 local selftests_dir="${kernel_checkout}/tools/testing/selftests/bpf"

 cd "${selftests_dir}"
 ${make_command}

 # Mount the image and copy the selftests to the image.
 mount_image
 sudo rm -rf "${mount_dir}/root/bpf"
 sudo cp -r "${selftests_dir}" "${mount_dir}/root"
 unmount_image
}

update_init_script()
{
 local init_script_dir="${OUTPUT_DIR}/${MOUNT_DIR}/etc/rcS.d"
 local init_script="${init_script_dir}/S50-startup"
 local command="$1"
 local exit_command="$2"

 mount_image

 if [[ ! -d "${init_script_dir}" ]]; then
  cat <<EOF
Could not find ${init_script_dir} in the mounted image.
This likely indicates a bad rootfs image, Please download
a new image by passing "-i" to the script
EOF
  exit 1

 fi

 sudo bash -c "echo '#!/bin/bash' > ${init_script}"

 if [[ "${command}" != "" ]]; then
  sudo bash -c "cat >>${init_script}" <<EOF
# Have a default value in the exit status file
# incase the VM is forcefully stopped.
echo "130" > "/root/${EXIT_STATUS_FILE}"

{
 cd /root/bpf
 echo ${command}
 stdbuf -oL -eL ${command}
 echo "\$?" > "/root/${EXIT_STATUS_FILE}"
} 2>&1 | tee "/root/${LOG_FILE}"
# Ensure that the logs are written to disk
sync
EOF
 fi

 sudo bash -c "echo ${exit_command} >> ${init_script}"
 sudo chmod a+x "${init_script}"
 unmount_image
}

create_vm_image()
{
 local rootfs_img="${OUTPUT_DIR}/${ROOTFS_IMAGE}"
 local mount_dir="${OUTPUT_DIR}/${MOUNT_DIR}"

 rm -rf "${rootfs_img}"
 touch "${rootfs_img}"
 chattr +C "${rootfs_img}" >/dev/null 2>&1 || true

 truncate -s 2G "${rootfs_img}"
 mkfs.ext4 -q "${rootfs_img}"

 mount_image
 load_rootfs "${mount_dir}"
 unmount_image
}

run_vm()
{
 local kernel_bzimage="$1"
 local rootfs_img="${OUTPUT_DIR}/${ROOTFS_IMAGE}"

 if ! which "${QEMU_BINARY}" &> /dev/null; then
  cat <<EOF
Could not find ${QEMU_BINARY}
Please install qemu or set the QEMU_BINARY environment variable.
EOF
  exit 1
 fi

 if [[ "${PLATFORM}" != "$(uname -m)" ]]; then
  QEMU_FLAGS=("${CROSS_FLAGS[@]}")
 else
  QEMU_FLAGS=("${HOST_FLAGS[@]}")
 fi

 ${QEMU_BINARY} \
  -nodefaults \
  -display none \
  -serial mon:stdio \
  "${QEMU_FLAGS[@]}" \
  -m 4G \
  -drive file="${rootfs_img}",format=raw,index=1,media=disk,if=virtio,cache=none \
  -kernel "${kernel_bzimage}" \
  -append "root=/dev/vda rw console=${QEMU_CONSOLE}"
}

copy_logs()
{
 local mount_dir="${OUTPUT_DIR}/${MOUNT_DIR}"
 local log_file="${mount_dir}/root/${LOG_FILE}"
 local exit_status_file="${mount_dir}/root/${EXIT_STATUS_FILE}"

 mount_image
 sudo cp ${log_file} "${OUTPUT_DIR}"
 sudo cp ${exit_status_file} "${OUTPUT_DIR}"
 sudo rm -f ${log_file}
 unmount_image
}

is_rel_path()
{
 local path="$1"

 [[ ${path:0:1} != "/" ]]
}

do_update_kconfig()
{
 local kernel_checkout="$1"
 local kconfig_file="$2"

 rm -f "$kconfig_file" 2> /dev/null

 for config in "${KCONFIG_REL_PATHS[@]}"do
  local kconfig_src="${kernel_checkout}/${config}"
  cat "$kconfig_src" >> "$kconfig_file"
 done
}

update_kconfig()
{
 local kernel_checkout="$1"
 local kconfig_file="$2"

 if [[ -f "${kconfig_file}" ]]; then
  local local_modified="$(stat -c %Y "${kconfig_file}")"

  for config in "${KCONFIG_REL_PATHS[@]}"do
   local kconfig_src="${kernel_checkout}/${config}"
   local src_modified="$(stat -c %Y "${kconfig_src}")"
   # Only update the config if it has been updated after the
   # previously cached config was created. This avoids
   # unnecessarily compiling the kernel and selftests.
   if [[ "${src_modified}" -gt "${local_modified}" ]]; then
    do_update_kconfig "$kernel_checkout" "$kconfig_file"
    # Once we have found one outdated configuration
    # there is no need to check other ones.
    break
   fi
  done
 else
  do_update_kconfig "$kernel_checkout" "$kconfig_file"
 fi
}

catch()
{
 local exit_code=$1
 local exit_status_file="${OUTPUT_DIR}/${EXIT_STATUS_FILE}"
 # This is just a cleanup and the directory may
 # have already been unmounted. So, don't let this
 # clobber the error code we intend to return.
 unmount_image || true
 if [[ -f "${exit_status_file}" ]]; then
  exit_code="$(cat ${exit_status_file})"
 fi
 exit ${exit_code}
}

main()
{
 local script_dir="$(cd -P -- "$(dirname -- "${BASH_SOURCE[0]}")" && pwd -P)"
 local kernel_checkout=$(realpath "${script_dir}"/../../../../)
 # By default the script searches for the kernel in the checkout directory but
 # it also obeys environment variables O= and KBUILD_OUTPUT=
 local kernel_bzimage="${kernel_checkout}/${BZIMAGE}"
 local command="${DEFAULT_COMMAND}"
 local update_image="no"
 local exit_command="poweroff -f"
 local debug_shell="no"

 while getopts ':hskl:id:j:' opt; do
  case ${opt} in
  l)
   LOCAL_ROOTFS_IMAGE="$OPTARG"
   ;;
  i)
   update_image="yes"
   ;;
  d)
   OUTPUT_DIR="$OPTARG"
   ;;
  j)
   NUM_COMPILE_JOBS="$OPTARG"
   ;;
  s)
   command=""
   debug_shell="yes"
   exit_command="bash"
   ;;
  h)
   usage
   exit 0
   ;;
  \? )
   echo "Invalid Option: -$OPTARG"
   usage
   exit 1
   ;;
  : )
   echo "Invalid Option: -$OPTARG requires an argument"
   usage
   exit 1
   ;;
  esac
 done
 shift $((OPTIND -1))

 trap 'catch "$?"' EXIT

 if [[ "${PLATFORM}" != "$(uname -m)" ]] && [[ -z "${CROSS_COMPILE}" ]]; then
  echo "Cross-platform testing needs to specify CROSS_COMPILE"
  exit 1
 fi

 if [[ $# -eq 0  && "${debug_shell}" == "no" ]]; then
  echo "No command specified, will run ${DEFAULT_COMMAND} in the vm"
 else
  command="$@"
 fi

 local kconfig_file="${OUTPUT_DIR}/latest.config"
 local make_command="make ARCH=${ARCH} CROSS_COMPILE=${CROSS_COMPILE} \
       -j ${NUM_COMPILE_JOBS} KCONFIG_CONFIG=${kconfig_file}"

 # Figure out where the kernel is being built.
 # O takes precedence over KBUILD_OUTPUT.
 if [[ "${O:=""}" != "" ]]; then
  if is_rel_path "${O}"then
   O="$(realpath "${PWD}/${O}")"
  fi
  kernel_bzimage="${O}/${BZIMAGE}"
  make_command="${make_command} O=${O}"
 elif [[ "${KBUILD_OUTPUT:=""}" != "" ]]; then
  if is_rel_path "${KBUILD_OUTPUT}"then
   KBUILD_OUTPUT="$(realpath "${PWD}/${KBUILD_OUTPUT}")"
  fi
  kernel_bzimage="${KBUILD_OUTPUT}/${BZIMAGE}"
  make_command="${make_command} KBUILD_OUTPUT=${KBUILD_OUTPUT}"
 fi

 local rootfs_img="${OUTPUT_DIR}/${ROOTFS_IMAGE}"
 local mount_dir="${OUTPUT_DIR}/${MOUNT_DIR}"

 echo "Output directory: ${OUTPUT_DIR}"

 mkdir -p "${OUTPUT_DIR}"
 mkdir -p "${mount_dir}"
 update_kconfig "${kernel_checkout}" "${kconfig_file}"

 recompile_kernel "${kernel_checkout}" "${make_command}"

 if [[ "${update_image}" == "no" && ! -f "${rootfs_img}" ]]; then
  echo "rootfs image not found in ${rootfs_img}"
  update_image="yes"
 fi

 if [[ "${update_image}" == "yes" ]]; then
  create_vm_image
 fi

 update_selftests "${kernel_checkout}" "${make_command}"
 update_init_script "${command}" "${exit_command}"
 run_vm "${kernel_bzimage}"
 if [[ "${command}" != "" ]]; then
  copy_logs
  echo "Logs saved in ${OUTPUT_DIR}/${LOG_FILE}"
 fi
}

main "$@"

Messung V0.5
C=95 H=90 G=92

¤ Dauer der Verarbeitung: 0.12 Sekunden  (vorverarbeitet)  ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

Beweissystem der NASA

Beweissystem Isabelle

NIST Cobol Testsuite

Cephes Mathematical Library

Wiener Entwicklungsmethode

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.