mirror of
https://github.com/AlbrechtL/openwrt-docker.git
synced 2026-10-17 00:01:27 +00:00
Add initial PCI pass-through support
This commit is contained in:
+4
-1
@@ -65,6 +65,7 @@ RUN echo "Building for platform '$TARGETPLATFORM'" \
|
||||
netcat-openbsd \
|
||||
uuidgen \
|
||||
usbutils \
|
||||
pciutils \
|
||||
openssh-client \
|
||||
util-linux-misc \
|
||||
iproute2 \
|
||||
@@ -152,12 +153,14 @@ RUN echo "Building for platform '$TARGETPLATFORM'" \
|
||||
&& until ssh root@localhost -p $SSH_PORT "${PACKAGE_UPDATE}"; do echo "Retrying ${PACKAGE_UPDATE} ..."; sleep 1; done\
|
||||
# Download Luci, qemu guest agent and mDNS support \
|
||||
&& ssh root@localhost -p $SSH_PORT "${PACKAGE_INSTALL} qemu-ga luci luci-ssl umdns losetup ${PACKAGE_EXTRA}" \
|
||||
# Download USB, PCI and PCIe support \
|
||||
&& ssh root@localhost -p $SSH_PORT "${PACKAGE_INSTALL} usbutils pciutils" \
|
||||
# Download Wi-Fi access point support and Wi-Fi USB devices support \
|
||||
&& ssh root@localhost -p $SSH_PORT "${PACKAGE_INSTALL} hostapd wpa-supplicant kmod-mt7921u" \
|
||||
# Download celluar network support \
|
||||
&& ssh root@localhost -p $SSH_PORT "${PACKAGE_INSTALL} modemmanager kmod-usb-net-qmi-wwan luci-proto-modemmanager qmi-utils" \
|
||||
# Download basic GPS support \
|
||||
&& ssh root@localhost -p $SSH_PORT "${PACKAGE_INSTALL} kmod-usb-serial usbutils minicom gpsd" \
|
||||
&& ssh root@localhost -p $SSH_PORT "${PACKAGE_INSTALL} kmod-usb-serial minicom gpsd" \
|
||||
# Add Wireguard support \
|
||||
&& ssh root@localhost -p $SSH_PORT "${PACKAGE_INSTALL} wireguard-tools luci-proto-wireguard" \
|
||||
# Add Power off script support \
|
||||
|
||||
+12
-2
@@ -28,12 +28,21 @@ services:
|
||||
# Make LuCI OpenWrt web interface accessible via host LAN
|
||||
FORWARD_LUCI: "true"
|
||||
|
||||
# USB passthrough
|
||||
# USB pass-through
|
||||
# Format <vendorID>:<productID> like 'lsusb' is given
|
||||
# Currently only two USB devices are supported
|
||||
#USB_1: "0bda:8153"
|
||||
#USB_2: "0e8d:7961"
|
||||
|
||||
# PCI and PCIe pass-through
|
||||
# Host system requirements
|
||||
# - IOMMU CPU feature has to enabled in bios
|
||||
# - Host kernel has to switch on intel_iommu=on or amd_iommu=on
|
||||
# - Host kernel module 'vfio-pci' has to exists
|
||||
# - Ubuntu 24.04 is working by default
|
||||
# Format <bus:device.function> like 'lspci' is given
|
||||
#PCI_1: "00:1f.6"
|
||||
|
||||
# Define number of VM CPUs
|
||||
# If unset -> 1
|
||||
#CPU_COUNT: 2
|
||||
@@ -48,6 +57,7 @@ services:
|
||||
#OPENWRT_AFTER_BOOT_CMD: "/usr/bin/fw_wan_open_http; /usr/bin/fw_wan_open_ssh" # Example to execute two commands
|
||||
#OPENWRT_AFTER_BOOT_CMD: "cat /etc/banner" # Custom commands example
|
||||
#OPENWRT_AFTER_BOOT_CMD: "a=$$((1+1)); echo The result of 1+1 is $${a}" # Shell script example
|
||||
#OPENWRT_AFTER_BOOT_CMD: '[ -f /etc/first_boot_over ] || { touch /etc/first_boot_over; echo "Crazy first boot"; }' # Example to run a command only once
|
||||
|
||||
#DEBUG: "y"
|
||||
|
||||
@@ -61,7 +71,7 @@ services:
|
||||
# Use script /usr/bin/fw_wan_open_ssh to open the port. Works only if WAN_IF=host
|
||||
#- 8022:8022
|
||||
stop_grace_period: 2m
|
||||
restart: on-failure
|
||||
#restart: on-failure
|
||||
|
||||
# The following settings are mandatory to run the container
|
||||
devices:
|
||||
|
||||
@@ -18,6 +18,7 @@ This Docker container brings you OpenWrt, a software-based router solution, in a
|
||||
- Attaches two physical Ethernet interfaces (LAN/WAN) exclusively into the docker container
|
||||
- Create virtual LAN between OpenWrt and host system (LAN only)
|
||||
- USB pass-through e.g. for modem or Wi-Fi dongles
|
||||
- PCI pass-through e.g. for Wi-Fi dongles or PCIe Ethernet cards
|
||||
- Automatic configuration migration when OpenWrt image is updated
|
||||
- Run shell commands inside OpenWrt after boot-up
|
||||
|
||||
|
||||
@@ -0,0 +1,25 @@
|
||||
#!/usr/bin/env bash
|
||||
set -Eeuo pipefail
|
||||
|
||||
. /run/helpers.sh
|
||||
|
||||
cleanup() {
|
||||
info "Container is stopping. Performing cleanup..."
|
||||
# Add your cleanup commands here
|
||||
|
||||
if [ -n "$PCI_1" ]; then
|
||||
echo "Attaching PCI device $PCI_1 back to the host"
|
||||
echo 1 > /sys/bus/pci/devices/0000:$PCI_1/remove
|
||||
echo 1 > /sys/bus/pci/rescan
|
||||
fi
|
||||
|
||||
echo "Cleanup complete."
|
||||
exit 0
|
||||
}
|
||||
|
||||
# Catch signals and call cleanup function
|
||||
trap cleanup SIGTERM SIGINT
|
||||
|
||||
# Wait forever to prevent that multirun will stop the complete container
|
||||
# This script purpose is only to catch the signal SIGTERM and SIGINT and to execute some last commands
|
||||
sleep infinity & wait
|
||||
@@ -14,6 +14,7 @@ trap 'error "Status $? while: $BASH_COMMAND (line $LINENO/$BASH_LINENO)"' ERR
|
||||
: "${LAN_IF:=""}" # Physical LAN interface name
|
||||
: "${USB_1:=""}" # USB 1 vendor and device ID
|
||||
: "${USB_2:=""}" # USB 2 vendor and device ID
|
||||
: "${PCI_1:=""}" # PCI 1 slot (first number in lspci)
|
||||
: "${FORWARD_LUCI:=""}" # Make LuCI OpenWrt web interface accessible via host LAN
|
||||
: "${OPENWRT_AFTER_BOOT_CMD:=""}" # User command or script to run after OpenWrt is booted
|
||||
: "${IS_U_OS_APP:=""}" # By default this container is not a u-OS app
|
||||
|
||||
@@ -45,13 +45,19 @@ echo "* Content of /var/vm/openwrt_metadata.conf *" > /var/www/system_info.txt
|
||||
cat /var/vm/openwrt_metadata.conf >> /var/www/system_info.txt
|
||||
echo $'\n' >> /var/www/system_info.txt
|
||||
|
||||
echo "* Enviroment variables *" >> /var/www/system_info.txt
|
||||
echo "* Environment variables *" >> /var/www/system_info.txt
|
||||
export >> /var/www/system_info.txt
|
||||
echo $'\n' >> /var/www/system_info.txt
|
||||
|
||||
echo "* USB devices *" >> /var/www/system_info.txt
|
||||
set +e # Enable that the next command can fail
|
||||
lsusb >> /var/www/system_info.txt
|
||||
echo $'\n' >> /var/www/system_info.txt
|
||||
set -e # Revert set +a
|
||||
|
||||
echo "* PCI devices *" >> /var/www/system_info.txt
|
||||
set +e # Enable that the next command can fail
|
||||
lspci >> /var/www/system_info.txt
|
||||
set -e # Revert set +a
|
||||
|
||||
# ******* nginx handling *******
|
||||
@@ -85,6 +91,7 @@ fi
|
||||
|
||||
# Start processes
|
||||
exec multirun \
|
||||
"/run/cleanup_container.sh" \
|
||||
"qemu-openwrt-web-backend" \
|
||||
"nginx" \
|
||||
"/run/run_openwrt.sh" \
|
||||
|
||||
+53
-2
@@ -135,6 +135,44 @@ attach_veth_if () {
|
||||
fi
|
||||
}
|
||||
|
||||
# Prepare PCI device for qemu
|
||||
attach_pci_device () {
|
||||
local PCI_DEVICE=$1
|
||||
local PCI_PATH="/sys/bus/pci/devices/$PCI_DEVICE"
|
||||
|
||||
info "Preparing PCI pass-through for device $PCI_DEVICE ..."
|
||||
|
||||
if [ ! -e "$PCI_PATH" ]; then
|
||||
echo "Error: PCI device $PCI_DEVICE not found"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Unbind from current driver
|
||||
local DRIVER=$(basename "$(readlink "$PCI_PATH/driver")" 2>/dev/null)
|
||||
if [ "$DRIVER" ]; then
|
||||
echo "Unbinding $PCI_DEVICE from $DRIVER"
|
||||
echo "$PCI_DEVICE" > "$PCI_PATH/driver/unbind"
|
||||
fi
|
||||
|
||||
# Ensure vfio-pci module is loaded
|
||||
if ! lsmod | grep -q '^vfio_pci ' ; then
|
||||
echo "Loading vfio-pci kernel module"
|
||||
nsenter --target 1 --uts --net --ipc --mount modprobe vfio-pci
|
||||
fi
|
||||
|
||||
# Bind to vfio-pci
|
||||
echo "vfio-pci" > "$PCI_PATH/driver_override"
|
||||
echo "$PCI_DEVICE" > /sys/bus/pci/drivers/vfio-pci/bind
|
||||
|
||||
# Verify binding
|
||||
if [ "$(basename "$(readlink "$PCI_PATH/driver" 2>/dev/null)")" != "vfio-pci" ]; then
|
||||
echo "Failed to bind $PCI_DEVICE to vfio-pci"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "Successfully bound $PCI_DEVICE to vfio-pci"
|
||||
}
|
||||
|
||||
# Handle dirfferent architectures
|
||||
if [ $CPU_ARCH = "aarch64" ]; then
|
||||
CPU_ARGS="-M virt -bios /usr/share/qemu/edk2-aarch64-code.fd -vga none -device ramfb"
|
||||
@@ -212,6 +250,20 @@ fi
|
||||
|
||||
USB_ARGS="${USB_1_ARGS} ${USB_2_ARGS}"
|
||||
|
||||
# Attaching PCI devices
|
||||
PCI_ARGS=""
|
||||
PCI_1_ARGS=""
|
||||
if [[ -z "$PCI_1" ]]; then
|
||||
PCI_1_ARGS=""
|
||||
else
|
||||
PCI_SLOT="0000:$PCI_1"
|
||||
attach_pci_device "$PCI_SLOT"
|
||||
PCI_1_ARGS="-device vfio-pci,host=$PCI_SLOT"
|
||||
fi
|
||||
|
||||
PCI_ARGS="${PCI_1_ARGS}"
|
||||
|
||||
|
||||
info "Booting image using $VERS..."
|
||||
|
||||
# See qemu command if debug is enabled
|
||||
@@ -230,9 +282,8 @@ exec qemu-system-"$CPU_ARCH" \
|
||||
$LAN_ARGS \
|
||||
$WAN_ARGS \
|
||||
$USB_ARGS \
|
||||
$PCI_ARGS \
|
||||
-qmp unix:/run/qmp-sock,server=on,wait=off \
|
||||
-chardev socket,path=/run/qga.sock,server=on,wait=off,id=qga0 \
|
||||
-device virtio-serial \
|
||||
-device virtserialport,chardev=qga0,name=org.qemu.guest_agent.0
|
||||
|
||||
# -kernel /var/vm/kernel.bin -append "root=fe00 console=tty0" \
|
||||
|
||||
Reference in New Issue
Block a user