mirror of
https://github.com/unraid/webgui.git
synced 2026-01-07 01:59:52 -06:00
213 lines
7.6 KiB
Bash
Executable File
213 lines
7.6 KiB
Bash
Executable File
#!/bin/bash
|
|
#
|
|
# script: rc.udev
|
|
#
|
|
# This is a script to initialize udev, which populates the /dev
|
|
# directory with device nodes, scans for devices, loads the
|
|
# appropriate kernel modules, and configures the devices.
|
|
#
|
|
# LimeTech - modified for Unraid OS
|
|
# Bergware - modified for Unraid OS, October 2023
|
|
|
|
# Set the path.
|
|
PATH=/sbin:/bin
|
|
|
|
# run & log functions
|
|
. /etc/rc.d/rc.runlog
|
|
|
|
check_mounted(){
|
|
grep -Eq "^[^[:space:]]+ $1 $2" /proc/mounts
|
|
}
|
|
|
|
mount_devpts(){
|
|
if ! check_mounted /dev/pts devpts; then
|
|
mkdir /dev/pts 2>/dev/null
|
|
mount -n -o mode=0620,gid=5 -t devpts devpts /dev/pts
|
|
fi
|
|
}
|
|
|
|
mount_devshm(){
|
|
if ! check_mounted /dev/shm tmpfs; then
|
|
mkdir /dev/shm 2>/dev/null
|
|
mount /dev/shm
|
|
fi
|
|
}
|
|
|
|
case "$1" in
|
|
'start')
|
|
# Sanity check #1, udev requires that the kernel support tmpfs:
|
|
if ! grep -wq tmpfs /proc/filesystems; then
|
|
log "Sorry, but you need tmpfs support in the kernel to use udev."
|
|
log "FATAL: Refusing to run /etc/rc.d/rc.udev."
|
|
exit 1
|
|
fi
|
|
# Sanity check #2, make sure that a 2.6.x kernel is new enough:
|
|
if [[ $(uname -r | cut -f 1,2 -d .) == 2.6 ]]; then
|
|
if [[ $(uname -r | cut -f 3 -d . | sed 's/[^[:digit:]].*//') -lt 32 ]]; then
|
|
log "Sorry, but you need a 2.6.32+ kernel to use this udev."
|
|
log "Your kernel version is only $(uname -r)."
|
|
log "FATAL: Refusing to run /etc/rc.d/rc.udev."
|
|
exit 1
|
|
fi
|
|
fi
|
|
# Sanity check #3, make sure the udev package was not removed. If udevd
|
|
# is not there, this will also shut off this script to prevent further
|
|
# problems:
|
|
if [[ ! -x /sbin/udevd ]]; then
|
|
chmod 0644 /etc/rc.d/rc.udev
|
|
log "No udevd daemon found."
|
|
log "Turning off udev: chmod 644 /etc/rc.d/rc.udev"
|
|
log "FATAL: Refusing to run /etc/rc.d/rc.udev."
|
|
exit 1
|
|
fi
|
|
# Disable hotplug helper since udevd listens to netlink:
|
|
if [[ -e /proc/sys/kernel/hotplug ]]; then
|
|
echo >/proc/sys/kernel/hotplug
|
|
fi
|
|
if grep -qw devtmpfs /proc/filesystems; then
|
|
if ! check_mounted /dev devtmpfs; then
|
|
# umount shm if needed
|
|
check_mounted /dev/shm tmpfs && umount -l /dev/shm
|
|
# Umount pts if needed, we will remount it later:
|
|
check_mounted /dev/pts devpts && umount -l /dev/pts
|
|
# Mount tmpfs on /dev:
|
|
mount -n -t devtmpfs -o size=8M devtmpfs /dev
|
|
fi
|
|
else
|
|
# Mount tmpfs on /dev:
|
|
if ! check_mounted /dev tmpfs; then
|
|
# umount shm if needed
|
|
check_mounted /dev/shm tmpfs && umount -l /dev/shm
|
|
# Umount pts if needed, we will remount it later:
|
|
check_mounted /dev/pts devpts && umount -l /dev/pts
|
|
# Mount tmpfs on /dev:
|
|
# the -n is because we don't want /dev umounted when
|
|
# someone (rc.[06]) calls umount -a
|
|
mount -n -o mode=0755 -t tmpfs -o size=8M tmpfs /dev
|
|
fi
|
|
fi
|
|
# Mount devpts
|
|
mount_devpts
|
|
mount_devshm
|
|
if ! pidof udevd &>/dev/null; then # start udevd
|
|
log "Creating static nodes in /dev."
|
|
run kmod static-nodes -f tmpfiles --output /run/static-nodes
|
|
grep "^d " /run/static-nodes | while read line; do
|
|
mkdir -p -m $(echo $line | cut -f 3 -d ' ') $(echo $line | cut -f 2 -d ' ')
|
|
done
|
|
grep -v "^d " /run/static-nodes | while read line; do
|
|
mknod -m $(echo $line | cut -f 3 -d ' ') \
|
|
$(echo $line | cut -f 2 -d ' ') \
|
|
$(echo $line | cut -b1 ) \
|
|
$(echo $line | cut -f 7 -d ' ' | cut -f 1 -d :) \
|
|
$(echo $line | cut -f 7 -d ' ' | cut -f 2 -d :) 2>/dev/null
|
|
done
|
|
rm -f /run/static-nodes
|
|
# Add any system defined additional device nodes:
|
|
cp --preserve=all --recursive --update /lib/udev/devices/* /dev 2>/dev/null
|
|
# Add any locally defined additional device nodes:
|
|
cp --preserve=all --recursive --update /etc/udev/devices/* /dev 2>/dev/null
|
|
log "Starting udevd..."
|
|
run udevd --daemon
|
|
# Since udev is just now being started we want to use add events:
|
|
log "Triggering udev events..."
|
|
# Call udevtrigger and udevsettle to do the device configuration:
|
|
run udevadm trigger --type=subsystems --action=add
|
|
run udevadm trigger --type=devices --action=add
|
|
else # trigger changes for already running udevd
|
|
# Bergware - set file references
|
|
RAM=/etc/udev/rules.d/70-persistent-net.rules
|
|
ROM=/boot/config/network-rules.cfg
|
|
MAC='ATTR{address}=="\K..:..:..:..:..:..'
|
|
# If the persistent network rules file does not exist, trigger an add event:
|
|
if [[ ! -r $RAM ]]; then
|
|
# Test that we can actually write to the directory first:
|
|
if touch /etc/udev/rules.d/testfile 2>/dev/null; then
|
|
rm -f /etc/udev/rules.d/testfile
|
|
# This should add persistent net rules:
|
|
log "Triggering udev to write persistent rules to /etc/udev/rules.d/"
|
|
run udevadm trigger --type=devices --action=add
|
|
sleep 3
|
|
# Create the files if they don't exist at this point.
|
|
# If a machine does not have a network device or an optical
|
|
# device, we don't want to waste time trying to generate
|
|
# rules at every boot.
|
|
# To force another attempt, delete the file(s).
|
|
touch $RAM
|
|
fi
|
|
fi
|
|
# Bergware - start of code
|
|
if [[ -f $ROM ]]; then
|
|
NEW=$(grep -Po $MAC $RAM | sort)
|
|
# Bergware - set persistent rules of existing interfaces
|
|
grep -B2 "$NEW" $ROM | /usr/bin/fromdos >$RAM
|
|
run udevadm control --reload
|
|
# Bergware - find the unique drivers currently in use by the interface(s)
|
|
DRIVERS=
|
|
for PORT in $(ls --indicator-style=none /sys/class/net | grep -P '^eth\d+$'); do
|
|
DRIVER=$(/usr/sbin/ethtool -i $PORT | grep -Po '^driver: \K\S+')
|
|
[[ $DRIVERS != *$DRIVER* ]] && DRIVERS="$DRIVERS $DRIVER"
|
|
done
|
|
# Bergware - delete existing interfaces and recreate them using the updated udev rules
|
|
modprobe -r $DRIVERS
|
|
modprobe -a $DRIVERS
|
|
# Bergware - check for changes and save them
|
|
if [[ $NEW != $(grep -Po $MAC $ROM | sort) ]]; then
|
|
# Bergware - copy to flash only when more than one interface is present
|
|
[[ $(echo "$NEW" | wc -l) -gt 1 ]] && /usr/bin/todos <$RAM >$ROM || rm -f $ROM
|
|
fi
|
|
else
|
|
# Bergware - remove leading remarks in file
|
|
sed -i '/^# This/,/^$/d' $RAM
|
|
# Bergware - copy to flash only when more than one interface is present
|
|
[[ $(grep -Pc 'NAME="eth\d+"' $RAM) -gt 1 ]] && /usr/bin/todos <$RAM >$ROM || rm -f $ROM
|
|
fi
|
|
# Bergware - end of code
|
|
# Update the hardware database index (/etc/udev/hwdb.bin), if possible:
|
|
if touch /etc/udev/testfile 2>/dev/null; then
|
|
rm -f /etc/udev/testfile
|
|
log "Updating hardware database index..."
|
|
run udevadm hwdb --update
|
|
fi
|
|
# Since udevd is running, most of the time we only need change events:
|
|
log "Triggering udev events..."
|
|
run udevadm trigger --type=subsystems --action=change
|
|
run udevadm trigger --type=devices --action=change
|
|
fi
|
|
run udevadm settle --timeout=120
|
|
;;
|
|
'stop')
|
|
log "Stopping udevd is STRONGLY discouraged and not supported."
|
|
log "If you are sure you want to do this, use 'force-stop' instead."
|
|
;;
|
|
'restart')
|
|
log "Restarting udevd is STRONGLY discouraged and not supported."
|
|
log "If you are sure you want to do this, use 'force-restart' instead."
|
|
;;
|
|
'reload')
|
|
log "Reloading udev rules"
|
|
udevadm control --reload
|
|
;;
|
|
'force-stop')
|
|
log "Stopping udevd"
|
|
udevadm control --exit
|
|
killall --ns $$ udevd 2>/dev/null
|
|
;;
|
|
'force-restart')
|
|
log "Restarting udevd"
|
|
udevadm control --exit
|
|
sleep 3
|
|
udevd --daemon
|
|
;;
|
|
'force-reload')
|
|
log "Updating all available device nodes in /dev"
|
|
udevadm control --reload
|
|
rm -rf /dev/.udev /dev/disk
|
|
cp --preserve=all --recursive --update /lib/udev/devices/* /dev 2>/dev/null
|
|
;;
|
|
*)
|
|
echo "Usage: $BASENAME start|stop|restart|reload|force-stop|force-restart|force-reload"
|
|
exit 1
|
|
esac
|
|
exit 0
|