scripts/kvm-check.sh
Rama main · réplica de lectura del repositorio original.
#!/usr/bin/env bash
set -u
failures=0
warnings=0
pass() {
printf '[PASS] %s\n' "$1"
}
warn() {
warnings=$((warnings + 1))
printf '[WARN] %s\n' "$1"
}
fail() {
failures=$((failures + 1))
printf '[FAIL] %s\n' "$1"
}
info() {
printf '[INFO] %s\n' "$1"
}
has_command() {
command -v "$1" >/dev/null 2>&1
}
print_header() {
printf '%s\n' 'KVM host environment check'
printf '%s\n' '=========================='
printf '%s\n' 'This checks host readiness only. It does not check whether Firecracker is installed.'
}
check_platform() {
printf '\n%s\n' '1. Host platform'
kernel_name=$(uname -s 2>/dev/null || printf 'unknown')
kernel_release=$(uname -r 2>/dev/null || printf 'unknown')
machine_arch=$(uname -m 2>/dev/null || printf 'unknown')
info "kernel: ${kernel_name} ${kernel_release}"
info "architecture: ${machine_arch}"
if [ "$kernel_name" = 'Linux' ]; then
pass 'Linux kernel detected.'
else
fail 'KVM requires a Linux host.'
fi
case "$machine_arch" in
x86_64 | amd64)
pass 'Supported CPU architecture detected: x86_64.'
;;
aarch64 | arm64)
pass 'Supported CPU architecture detected: aarch64.'
;;
*)
fail "Unsupported or unknown CPU architecture: ${machine_arch}"
;;
esac
}
check_cpu_virtualization() {
printf '\n%s\n' '2. CPU virtualization'
if [ ! -r /proc/cpuinfo ]; then
fail '/proc/cpuinfo is not readable.'
return
fi
machine_arch=$(uname -m 2>/dev/null || printf 'unknown')
case "$machine_arch" in
x86_64 | amd64)
virt_count=$(grep -Eoc '(vmx|svm)' /proc/cpuinfo 2>/dev/null || true)
if [ "${virt_count:-0}" -gt 0 ]; then
pass "CPU virtualization flag found. count=${virt_count}"
else
fail 'CPU virtualization flag was not found. Expected vmx or svm in /proc/cpuinfo.'
fi
;;
aarch64 | arm64)
warn 'Skipping vmx/svm CPU flag check on ARM. /dev/kvm availability is the decisive check.'
;;
*)
warn "Skipping CPU virtualization flag check for unsupported architecture: ${machine_arch}"
;;
esac
}
check_kvm_device() {
printf '\n%s\n' '3. /dev/kvm device'
if [ ! -e /dev/kvm ]; then
fail '/dev/kvm does not exist. KVM may be disabled or unavailable in this host.'
return
fi
if [ ! -c /dev/kvm ]; then
fail '/dev/kvm exists but is not a character device.'
else
pass '/dev/kvm exists as a character device.'
fi
if has_command stat; then
mode=$(stat -c '%A %U %G' /dev/kvm 2>/dev/null || true)
if [ -n "${mode:-}" ]; then
info "/dev/kvm permission: ${mode}"
fi
else
ls -l /dev/kvm 2>/dev/null || true
fi
}
check_user_access() {
printf '\n%s\n' '4. Current user access'
current_user=$(id -un 2>/dev/null || printf 'unknown')
info "current user: ${current_user}"
info "groups: $(id -nG 2>/dev/null || printf 'unknown')"
if [ ! -e /dev/kvm ]; then
warn 'Cannot check user access because /dev/kvm does not exist.'
return
fi
if [ -r /dev/kvm ] && [ -w /dev/kvm ]; then
pass 'Current user can read and write /dev/kvm.'
else
fail 'Current user cannot read and write /dev/kvm.'
warn "Add the checked user to the kvm group, then log out and log back in: sudo usermod -aG kvm \"${current_user}\""
fi
if id -nG 2>/dev/null | tr ' ' '\n' | grep -qx 'kvm'; then
pass 'Current user is in the kvm group.'
else
warn 'Current user is not in the kvm group. Direct ACL/root access may still work, but kvm group membership is the common setup.'
fi
}
check_kvm_module() {
printf '\n%s\n' '5. KVM kernel support'
machine_arch=$(uname -m 2>/dev/null || printf 'unknown')
if [ -d /sys/module/kvm ]; then
pass 'kvm is present in /sys/module.'
elif [ -r /proc/modules ] && grep -q '^kvm ' /proc/modules; then
pass 'kvm module is listed in /proc/modules.'
elif [ -e /dev/kvm ]; then
info 'kvm is not listed as a loaded module, but /dev/kvm exists. KVM may be built into the kernel.'
elif [ -r /proc/modules ]; then
warn 'kvm module is not listed in /proc/modules.'
else
warn '/proc/modules is not readable and /sys/module/kvm is not present. Skipping kernel module check.'
fi
case "$machine_arch" in
x86_64 | amd64)
if [ -d /sys/module/kvm_intel ] || [ -d /sys/module/kvm_amd ]; then
pass 'x86 vendor KVM module is present in /sys/module.'
elif [ -r /proc/modules ] && grep -Eq '^kvm_intel |^kvm_amd ' /proc/modules; then
pass 'x86 vendor KVM module is listed in /proc/modules.'
elif [ -e /dev/kvm ]; then
info 'x86 vendor KVM module is not listed, but /dev/kvm exists. KVM may be built into the kernel.'
elif [ -r /proc/modules ]; then
warn 'x86 vendor KVM module is not listed. Expected kvm_intel or kvm_amd.'
else
warn '/proc/modules is not readable. Skipping x86 vendor KVM module check.'
fi
;;
aarch64 | arm64)
info 'Skipping x86 vendor KVM module check on ARM.'
;;
*)
info "Skipping x86 vendor KVM module check for architecture: ${machine_arch}"
;;
esac
}
print_summary() {
printf '\n%s\n' 'Summary'
printf '%s\n' '-------'
printf 'failures=%s warnings=%s\n' "$failures" "$warnings"
if [ "$failures" -eq 0 ]; then
printf '%s\n' 'Result: KVM host checks passed.'
exit 0
fi
printf '%s\n' 'Result: KVM host checks failed.'
exit 1
}
main() {
print_header
check_platform
check_cpu_virtualization
check_kvm_device
check_user_access
check_kvm_module
print_summary
}
main "$@"