init: Move all copy of files to before udev triger is run

This since we may copy udev-rules dependeing on platforms,
this fix #1357

Also remove all workaround scripts we have added for this
purpose.
This commit is contained in:
Mattias Walström
2026-02-21 09:25:25 +01:00
parent ef7ed89443
commit 4aa0ab73b3
8 changed files with 73 additions and 39 deletions
@@ -1,3 +0,0 @@
#!/bin/sh
udevadm control --reload-rules
udevadm trigger --subsystem-match=net --action=add
@@ -1,3 +0,0 @@
#!/bin/sh
udevadm control --reload-rules
udevadm trigger --subsystem-match=net --action=add
@@ -1,4 +0,0 @@
#!/bin/sh
# Workaround for: https://github.com/kernelkit/infix/issues/1357
udevadm control --reload-rules
udevadm trigger --subsystem-match=net --action=add
@@ -1,4 +0,0 @@
#!/bin/sh
# Workaround for: https://github.com/kernelkit/infix/issues/1357
udevadm control --reload-rules
udevadm trigger --subsystem-match=net --action=add
@@ -0,0 +1,18 @@
# Copy product-specific files (udev rules, factory config, etc.) to /
# based on DT compatible strings, before udevd processes any events.
#
# <hook/mount/all> fires after all filesystems are mounted but before
# finit enters runlevel S and starts any service, so the run task is
# guaranteed to start ahead of udevd. The <run/preudev/success>
# condition below then blocks udevd until pre-udev has finished.
#
# Systems without a matching product directory exit immediately.
run name:preudev cgroup.init [S] <hook/mount/all> log \
/usr/libexec/infix/pre-udev -- Probing platform
# Hold udevd back until pre-udev has had a chance to install any
# product-specific udev rules so that they are applied on first pass.
service nowarn cgroup.system name:udevd notify:none env:-/etc/default/udevd pid:udevd log \
[S12345789] <run/preudev/success> /lib/systemd/systemd-udevd $UDEVD_ARGS -- Device event daemon (udev)
service nowarn cgroup.system name:udevd notify:none env:-/etc/default/udevd pid:udevd log \
[S12345789] <run/preudev/success> udevd $UDEVD_ARGS -- Device event daemon (udev)
@@ -5,5 +5,5 @@ run nowarn if:udevd cgroup.init <service/udevd/ready> log \
# Now that everything should be probed, do a final pass over the
# uevent queue before starting syslogd and everything else
run nowarn if:udevd cgroup.init :post <service/udevd/ready> log \
run nowarn if:udevd cgroup.init :post <run/preudev/success,service/udevd/ready> log \
[S] udevadm settle -t 30 --
@@ -1,40 +1,22 @@
#!/bin/sh
# Find, install, and run product specific files and script in /etc
# before resuming bootstrap.
# Run product specific init scripts and set bootstrap conditions.
#
# Product-specific files (udev rules, factory config, etc.) are already
# copied to / by the pre-udev run task before udevd starts. This
# script handles the remaining product init: running custom scripts
# from /etc/product/init.d/ and setting finit conditions.
#
# Use /etc/product/init.d/S01-myscript for scripts, may be a symlink, it
# will be called with `start` as its only argument.
#
# The compatible array is listed in the same order as the device tree,
# most significant to least. Hence the reverse.[], to ensure overrides
# are applied in order of significance.
ident=$(basename "$0")
PRODUCT_INIT=/etc/product/init.d
PREFIXD=/usr/share/product
COMPATIBLES=$(jq -r '.compatible | reverse.[] | ascii_downcase' /run/system.json)
note()
{
logger -I $$ -k -p user.notice -t "$ident" "$1"
}
found=false
for PRODUCT in $COMPATIBLES; do
DIR="$PREFIXD/$PRODUCT"
if [ -d "$DIR" ]; then
note "Using vendor/product-specific defaults for $PRODUCT."
for dir in "$DIR"/*; do
[ -d "$dir" ] && cp -a "$dir" /
done
found=true
fi
done
if [ "$found" = false ]; then
note "No vendor/product-specific directory found, using built-in defaults."
fi
# Conditions for bootstrap services, this enables product specific
# init scripts to prevent select services from starting.
initctl -nbq cond set led
+48
View File
@@ -0,0 +1,48 @@
#!/bin/sh
# Copy product-specific files to / based on DT compatible strings.
# Designed to run before udevd, so that udev rules are in place when
# the kernel starts enumerating devices. No Python, no jq, no syslogd.
#
# Mirrors the platform detection from 00-probe and the copy logic from
# 05-product, but reads the DT directly instead of /run/system.json.
PREFIXD=/usr/share/product
COMPAT=/sys/firmware/devicetree/base/compatible
IDENT=$(basename "$0")
note()
{
logger -I $$ -k -p user.notice -t "$IDENT" "$*"
}
# Only DT-based systems have product-specific data keyed by compatible.
# QEMU and x86/DMI systems have no product dirs to copy.
[ -f "$COMPAT" ] || exit 0
# The DT compatible property is a null-separated list of strings,
# ordered most-specific first (e.g. "bananapi,bpi-r3\0mediatek,mt7986a").
# Reverse the list so least-specific is applied first and more-specific
# overrides it, matching the behaviour of 05-product.
reversed=""
while IFS= read -r c; do
[ -n "$c" ] || continue
reversed="$c${reversed:+ $reversed}"
done <<EOF
$(tr '\0' '\n' < "$COMPAT" | tr '[:upper:]' '[:lower:]')
EOF
found=false
for compat in $reversed; do
dir="$PREFIXD/$compat"
[ -d "$dir" ] || continue
note "Using product-specific defaults for $compat."
for subdir in "$dir"/*; do
[ -d "$subdir" ] && cp -a "$subdir" /
done
found=true
done
$found || note "No product-specific directory found, using built-in defaults."
exit 0