Refactor GPU passthrough logic in build.func
Some checks failed
Bump build.func Revision / bump-revision (push) Has been cancelled
Some checks failed
Bump build.func Revision / bump-revision (push) Has been cancelled
Simplifies and streamlines GPU passthrough configuration for LXC containers, consolidating device detection, selection, and userland package installation. Reduces code duplication, improves readability, and adds direct verification steps for VAAPI and NVIDIA support after installation.
This commit is contained in:
parent
6560a7c212
commit
633ca3edee
264
misc/build.func
264
misc/build.func
@ -2170,16 +2170,13 @@ build_container() {
|
||||
# Get device GID dynamically
|
||||
get_device_gid() {
|
||||
local group="$1"
|
||||
local gid
|
||||
gid=$(getent group "$group" 2>/dev/null | cut -d: -f3)
|
||||
if [[ -z "$gid" ]]; then
|
||||
gid=$(getent group "$group" | cut -d: -f3)
|
||||
[[ -n "$gid" ]] && echo "$gid" && return
|
||||
case "$group" in
|
||||
video) gid=44 ;;
|
||||
render) gid=104 ;;
|
||||
*) gid=44 ;;
|
||||
video) echo 44 ;;
|
||||
render) echo 104 ;;
|
||||
*) echo 44 ;;
|
||||
esac
|
||||
fi
|
||||
echo "$gid"
|
||||
}
|
||||
|
||||
# Check if app needs GPU
|
||||
@ -2192,24 +2189,18 @@ build_container() {
|
||||
}
|
||||
|
||||
# Detect available GPU devices
|
||||
is_gpu_app() {
|
||||
local app="${1,,}"
|
||||
for gpu in "${GPU_APPS[@]}"; do
|
||||
[[ "$gpu" == "$app" ]] && return 0
|
||||
done
|
||||
return 1
|
||||
}
|
||||
|
||||
detect_gpu_devices() {
|
||||
VAAPI_DEVICES=()
|
||||
NVIDIA_DEVICES=()
|
||||
|
||||
# VAAPI / Intel / AMD
|
||||
for device in /dev/dri/renderD* /dev/dri/card*; do
|
||||
[[ -e "$device" ]] || continue
|
||||
VAAPI_DEVICES+=("$device")
|
||||
done
|
||||
|
||||
# NVIDIA
|
||||
for device in /dev/nvidia*; do
|
||||
[[ -e "$device" ]] || continue
|
||||
NVIDIA_DEVICES+=("$device")
|
||||
done
|
||||
|
||||
msg_debug "Detected VAAPI devices: ${VAAPI_DEVICES[*]:-(none)}"
|
||||
msg_debug "Detected NVIDIA devices: ${NVIDIA_DEVICES[*]:-(none)}"
|
||||
VAAPI_DEVICES=(); NVIDIA_DEVICES=()
|
||||
for d in /dev/dri/renderD* /dev/dri/card*; do [[ -e $d ]] && VAAPI_DEVICES+=("$d"); done
|
||||
for d in /dev/nvidia*; do [[ -e $d ]] && NVIDIA_DEVICES+=("$d"); done
|
||||
}
|
||||
|
||||
# Configure USB passthrough for privileged containers
|
||||
@ -2233,142 +2224,64 @@ lxc.mount.entry: /dev/ttyACM1 dev/ttyACM1 none bind,optional,create=
|
||||
EOF
|
||||
msg_ok "USB passthrough configured"
|
||||
}
|
||||
|
||||
# Configure VAAPI device
|
||||
configure_vaapi_device() {
|
||||
local device="$1"
|
||||
local dev_index="$2"
|
||||
|
||||
local dev="$1" idx="$2"
|
||||
if [[ "$CT_TYPE" == "0" ]]; then
|
||||
# Privileged container
|
||||
local major minor
|
||||
major=$(stat -c '%t' "$device")
|
||||
minor=$(stat -c '%T' "$device")
|
||||
major=$((0x$major))
|
||||
minor=$((0x$minor))
|
||||
echo "lxc.cgroup2.devices.allow: c $major:$minor rwm" >>"$LXC_CONFIG"
|
||||
echo "lxc.mount.entry: $device dev/$(basename "$device") none bind,optional,create=file" >>"$LXC_CONFIG"
|
||||
major=$(stat -c '%t' "$dev"); minor=$(stat -c '%T' "$dev")
|
||||
echo "lxc.cgroup2.devices.allow: c $((0x$major)):$((0x$minor)) rwm" >>"$LXC_CONFIG"
|
||||
echo "lxc.mount.entry: $dev dev/$(basename "$dev") none bind,optional,create=file" >>"$LXC_CONFIG"
|
||||
else
|
||||
# Unprivileged container
|
||||
local gid
|
||||
if [[ "$device" =~ renderD ]]; then
|
||||
gid=$(get_device_gid "render")
|
||||
else
|
||||
gid=$(get_device_gid "video")
|
||||
fi
|
||||
echo "dev${dev_index}: $device,gid=$gid" >>"$LXC_CONFIG"
|
||||
[[ "$dev" =~ renderD ]] && gid=$(get_device_gid "render") || gid=$(get_device_gid "video")
|
||||
echo "dev$idx: $dev,gid=$gid" >>"$LXC_CONFIG"
|
||||
fi
|
||||
}
|
||||
|
||||
# Configure NVIDIA devices
|
||||
configure_nvidia_devices() {
|
||||
for device in "${NVIDIA_DEVICES[@]}"; do
|
||||
for dev in "${NVIDIA_DEVICES[@]}"; do
|
||||
if [[ "$CT_TYPE" == "0" ]]; then
|
||||
local major minor
|
||||
major=$(stat -c '%t' "$device")
|
||||
minor=$(stat -c '%T' "$device")
|
||||
major=$((0x$major))
|
||||
minor=$((0x$minor))
|
||||
echo "lxc.cgroup2.devices.allow: c $major:$minor rwm" >>"$LXC_CONFIG"
|
||||
echo "lxc.mount.entry: $device dev/$(basename "$device") none bind,optional,create=file" >>"$LXC_CONFIG"
|
||||
major=$(stat -c '%t' "$dev"); minor=$(stat -c '%T' "$dev")
|
||||
echo "lxc.cgroup2.devices.allow: c $((0x$major)):$((0x$minor)) rwm" >>"$LXC_CONFIG"
|
||||
echo "lxc.mount.entry: $dev dev/$(basename "$dev") none bind,optional,create=file" >>"$LXC_CONFIG"
|
||||
else
|
||||
msg_warn "NVIDIA passthrough to unprivileged container may require additional configuration"
|
||||
msg_warn "NVIDIA passthrough on unprivileged CT may fail"
|
||||
fi
|
||||
done
|
||||
|
||||
if [[ -d /dev/dri ]] && [[ "$CT_TYPE" == "0" ]]; then
|
||||
echo "lxc.mount.entry: /dev/dri dev/dri none bind,optional,create=dir" >>"$LXC_CONFIG"
|
||||
fi
|
||||
[[ -d /dev/dri && "$CT_TYPE" == "0" ]] && echo "lxc.mount.entry: /dev/dri dev/dri none bind,optional,create=dir" >>"$LXC_CONFIG"
|
||||
}
|
||||
|
||||
# Main GPU configuration logic
|
||||
configure_gpu_passthrough() {
|
||||
detect_gpu_devices
|
||||
local should=false
|
||||
if [[ "$CT_TYPE" == "0" ]] || is_gpu_app "$APP"; then should=true; fi
|
||||
[[ "$should" == "false" ]] && return
|
||||
|
||||
# Check if we should configure GPU
|
||||
local should_configure=false
|
||||
if [[ "$CT_TYPE" == "0" ]] || is_gpu_app "$APP"; then
|
||||
should_configure=true
|
||||
if [[ ${#VAAPI_DEVICES[@]} -eq 0 && ${#NVIDIA_DEVICES[@]} -eq 0 ]]; then
|
||||
msg_info "No GPU devices found"; return
|
||||
fi
|
||||
|
||||
if [[ "$should_configure" == "false" ]]; then
|
||||
return 0
|
||||
fi
|
||||
local choices=() selected=()
|
||||
[[ ${#VAAPI_DEVICES[@]} -gt 0 ]] && choices+=("VAAPI" "Intel/AMD GPU" "OFF")
|
||||
[[ ${#NVIDIA_DEVICES[@]} -gt 0 ]] && choices+=("NVIDIA" "NVIDIA GPU" "OFF")
|
||||
|
||||
# No GPU devices available
|
||||
if [[ ${#VAAPI_DEVICES[@]} -eq 0 ]] && [[ ${#NVIDIA_DEVICES[@]} -eq 0 ]]; then
|
||||
msg_info "No GPU devices detected on host"
|
||||
return 0
|
||||
fi
|
||||
|
||||
# Build selection options
|
||||
local choices=()
|
||||
local SELECTED_GPUS=()
|
||||
|
||||
if [[ ${#VAAPI_DEVICES[@]} -gt 0 ]]; then
|
||||
choices+=("VAAPI" "Intel/AMD GPU (${#VAAPI_DEVICES[@]} devices)" "OFF")
|
||||
fi
|
||||
|
||||
if [[ ${#NVIDIA_DEVICES[@]} -gt 0 ]]; then
|
||||
choices+=("NVIDIA" "NVIDIA GPU (${#NVIDIA_DEVICES[@]} devices)" "OFF")
|
||||
fi
|
||||
|
||||
# Auto-select if only one type available
|
||||
if [[ ${#choices[@]} -eq 3 ]]; then
|
||||
SELECTED_GPUS=("${choices[0]}")
|
||||
msg_info "Auto-configuring ${choices[0]} GPU passthrough"
|
||||
elif [[ ${#choices[@]} -gt 3 ]]; then
|
||||
# Show selection dialog
|
||||
local selected
|
||||
selected=$(whiptail --title "GPU Passthrough Selection" \
|
||||
--checklist "Multiple GPU types detected. Select which to pass through:" \
|
||||
12 60 $((${#choices[@]} / 3)) \
|
||||
"${choices[@]}" 3>&1 1>&2 2>&3) || {
|
||||
msg_info "GPU passthrough skipped"
|
||||
return 0
|
||||
}
|
||||
|
||||
for item in $selected; do
|
||||
SELECTED_GPUS+=("${item//\"/}")
|
||||
done
|
||||
selected=("VAAPI")
|
||||
elif [[ ${#choices[@]} -eq 6 ]]; then
|
||||
read -rp "Multiple GPUs found (VAAPI/NVIDIA). Which passthrough? " sel
|
||||
[[ "$sel" =~ VAAPI|vaapi ]] && selected=("VAAPI")
|
||||
[[ "$sel" =~ NVIDIA|nvidia ]] && selected=("NVIDIA")
|
||||
fi
|
||||
|
||||
# Apply configuration for selected GPUs
|
||||
local dev_index=0
|
||||
for gpu_type in "${SELECTED_GPUS[@]}"; do
|
||||
case "$gpu_type" in
|
||||
VAAPI)
|
||||
msg_info "Configuring VAAPI passthrough (${#VAAPI_DEVICES[@]} devices)"
|
||||
for device in "${VAAPI_DEVICES[@]}"; do
|
||||
configure_vaapi_device "$device" "$dev_index"
|
||||
: "${dev_index:=0}"
|
||||
dev_index=$((dev_index + 1))
|
||||
done
|
||||
if [[ "$CT_TYPE" == "0" ]] && [[ -d /dev/dri ]]; then
|
||||
echo "lxc.mount.entry: /dev/dri dev/dri none bind,optional,create=dir" >>"$LXC_CONFIG"
|
||||
fi
|
||||
export ENABLE_VAAPI=1
|
||||
;;
|
||||
NVIDIA)
|
||||
msg_info "Configuring NVIDIA passthrough"
|
||||
configure_nvidia_devices
|
||||
export ENABLE_NVIDIA=1
|
||||
;;
|
||||
local idx=0
|
||||
for s in "${selected[@]}"; do
|
||||
case "$s" in
|
||||
VAAPI) for d in "${VAAPI_DEVICES[@]}"; do configure_vaapi_device "$d" "$idx"; idx=$((idx+1)); done; export ENABLE_VAAPI=1 ;;
|
||||
NVIDIA) configure_nvidia_devices; export ENABLE_NVIDIA=1 ;;
|
||||
esac
|
||||
done
|
||||
|
||||
[[ ${#SELECTED_GPUS[@]} -gt 0 ]] && msg_ok "GPU passthrough configured"
|
||||
|
||||
[[ ${#selected[@]} -gt 0 ]] && msg_ok "GPU passthrough configured"
|
||||
}
|
||||
|
||||
# ------------------------------------------------------------------------------
|
||||
# Apply all hardware passthrough configurations
|
||||
# ------------------------------------------------------------------------------
|
||||
|
||||
# USB passthrough (automatic for privileged)
|
||||
configure_usb_passthrough
|
||||
|
||||
# GPU passthrough (based on container type and app)
|
||||
configure_gpu_passthrough
|
||||
|
||||
# TUN device passthrough
|
||||
@ -2438,67 +2351,30 @@ EOF
|
||||
fi
|
||||
fi
|
||||
|
||||
# # Install GPU userland packages
|
||||
# install_gpu_userland() {
|
||||
# local gpu_type="$1"
|
||||
install_gpu_userland() {
|
||||
local gpu="$1"
|
||||
if [[ "$var_os" == "alpine" ]]; then
|
||||
case "$gpu" in
|
||||
VAAPI) pct exec "$CTID" -- apk add mesa-dri-gallium mesa-va-gallium intel-media-driver libva-utils ;;
|
||||
NVIDIA) msg_warn "NVIDIA drivers not in Alpine repos" ;;
|
||||
esac
|
||||
else
|
||||
case "$gpu" in
|
||||
VAAPI) pct exec "$CTID" -- bash -c "apt-get update && apt-get install -y intel-media-va-driver-non-free mesa-va-drivers vainfo" ;;
|
||||
NVIDIA) pct exec "$CTID" -- bash -c "apt-get update && apt-get install -y nvidia-driver nvidia-utils libnvidia-encode1" ;;
|
||||
esac
|
||||
fi
|
||||
}
|
||||
|
||||
# if [ "$var_os" == "alpine" ]; then
|
||||
# case "$gpu_type" in
|
||||
# VAAPI)
|
||||
# msg_info "Installing VAAPI packages in Alpine container"
|
||||
# pct exec "$CTID" -- ash -c '
|
||||
# apk add --no-cache \
|
||||
# mesa-dri-gallium \
|
||||
# mesa-va-gallium \
|
||||
# intel-media-driver \
|
||||
# libva-utils >/dev/null 2>&1
|
||||
# ' || msg_warn "Some VAAPI packages may not be available in Alpine"
|
||||
# ;;
|
||||
# NVIDIA)
|
||||
# msg_warn "NVIDIA drivers are not readily available in Alpine Linux"
|
||||
# ;;
|
||||
# esac
|
||||
# else
|
||||
# case "$gpu_type" in
|
||||
# VAAPI)
|
||||
# msg_info "Installing VAAPI userland packages"
|
||||
# pct exec "$CTID" -- bash -c '
|
||||
# . /etc/os-release || true
|
||||
# if [[ "${VERSION_CODENAME:-}" == "trixie" ]]; then
|
||||
# cat >/etc/apt/sources.list.d/non-free.sources <<EOF
|
||||
# Types: deb deb-src
|
||||
# URIs: http://deb.debian.org/debian
|
||||
# Suites: trixie trixie-updates trixie-security
|
||||
# Components: non-free non-free-firmware
|
||||
# EOF
|
||||
# fi
|
||||
# apt-get update >/dev/null 2>&1
|
||||
# DEBIAN_FRONTEND=noninteractive apt-get install -y \
|
||||
# intel-media-va-driver-non-free \
|
||||
# mesa-va-drivers \
|
||||
# libvpl2 \
|
||||
# vainfo \
|
||||
# ocl-icd-libopencl1 \
|
||||
# mesa-opencl-icd \
|
||||
# intel-gpu-tools >/dev/null 2>&1
|
||||
# ' && msg_ok "VAAPI userland installed" || msg_warn "Some VAAPI packages failed to install"
|
||||
# ;;
|
||||
# NVIDIA)
|
||||
# msg_info "Installing NVIDIA userland packages"
|
||||
# pct exec "$CTID" -- bash -c '
|
||||
# apt-get update >/dev/null 2>&1
|
||||
# DEBIAN_FRONTEND=noninteractive apt-get install -y \
|
||||
# nvidia-driver \
|
||||
# nvidia-utils \
|
||||
# libnvidia-encode1 \
|
||||
# libcuda1 >/dev/null 2>&1
|
||||
# ' && msg_ok "NVIDIA userland installed" || msg_warn "Some NVIDIA packages failed to install"
|
||||
# ;;
|
||||
# esac
|
||||
# fi
|
||||
# }
|
||||
|
||||
# Customize container
|
||||
if [[ "${ENABLE_VAAPI:-0}" == "1" ]]; then
|
||||
install_gpu_userland "VAAPI"
|
||||
pct exec "$CTID" -- bash -c "chgrp video /dev/dri && chmod 755 /dev/dri && chmod 660 /dev/dri/*"
|
||||
pct exec "$CTID" -- vainfo >/dev/null 2>&1 && msg_ok "VAAPI verified" || msg_warn "VAAPI failed"
|
||||
fi
|
||||
if [[ "${ENABLE_NVIDIA:-0}" == "1" ]]; then
|
||||
install_gpu_userland "NVIDIA"
|
||||
pct exec "$CTID" -- nvidia-smi >/dev/null 2>&1 && msg_ok "NVIDIA verified" || msg_warn "NVIDIA failed"
|
||||
fi
|
||||
msg_info "Customizing LXC Container"
|
||||
|
||||
# # Install GPU userland if configured
|
||||
|
Loading…
x
Reference in New Issue
Block a user