switch to initqueue handling of events

Jobs are no longer handled inside the udev events.
/sbin/initqueue is called with the commands to queue.
init will work on these jobs sequentially, so that we prevent jobs
from being killed by udev timeouts.
This serialization also prevents some problems introduced by
the udev event parallelization.
master
Harald Hoyer 2009-07-02 11:42:35 +02:00
parent 4ce1991856
commit eab677a216
8 changed files with 49 additions and 12 deletions

View File

@ -19,20 +19,20 @@ fix_bootif() {
BOOTIF=$(getarg 'BOOTIF=') BOOTIF=$(getarg 'BOOTIF=')
if [ -n "$BOOTIF" ] ; then if [ -n "$BOOTIF" ] ; then
BOOTIF=$(fix_bootif "$BOOTIF") BOOTIF=$(fix_bootif "$BOOTIF")
printf 'ACTION=="add", SUBSYSTEM=="net", ATTR{address}=="%s", RUN+="/sbin/ifup $env{INTERFACE}"\n' "$BOOTIF" printf 'ACTION=="add", SUBSYSTEM=="net", ATTR{address}=="%s", RUN+="/sbin/initqueue /sbin/ifup $env{INTERFACE}"\n' "$BOOTIF"


# If we have to handle multiple interfaces, handle only them. # If we have to handle multiple interfaces, handle only them.
elif [ -n "$IFACES" ] ; then elif [ -n "$IFACES" ] ; then
for iface in $IFACES ; do for iface in $IFACES ; do
printf 'ACTION=="add", SUBSYSTEM=="net", KERNEL=="%s", RUN+="/sbin/ifup $env{INTERFACE}"\n' "$iface" printf 'ACTION=="add", SUBSYSTEM=="net", KERNEL=="%s", RUN+="/sbin/initqueue /sbin/ifup $env{INTERFACE}"\n' "$iface"
done done


# Default: We don't know the interface to use, handle all # Default: We don't know the interface to use, handle all
else else
printf 'ACTION=="add", SUBSYSTEM=="net", RUN+="/sbin/ifup $env{INTERFACE}"\n' printf 'ACTION=="add", SUBSYSTEM=="net", RUN+="/sbin/initqueue /sbin/ifup $env{INTERFACE}"\n'
fi fi


# Udev event 'online' only gets fired from ifup/dhclient-script. # Udev event 'online' only gets fired from ifup/dhclient-script.
# No special rules required # No special rules required
printf 'ACTION=="online", SUBSYSTEM=="net", RUN+="/sbin/netroot $env{INTERFACE}"\n' printf 'ACTION=="online", SUBSYSTEM=="net", RUN+="/sbin/initqueue /sbin/netroot $env{INTERFACE}"\n'
} > /etc/udev/rules.d/60-net.rules } > /etc/udev/rules.d/60-net.rules

View File

@ -7,6 +7,6 @@
SUBSYSTEM!="block", GOTO="luks_end" SUBSYSTEM!="block", GOTO="luks_end"
ACTION!="add|change", GOTO="luks_end" ACTION!="add|change", GOTO="luks_end"


ENV{ID_FS_TYPE}=="crypto_LUKS", RUN+="/sbin/cryptroot-ask $env{DEVNAME} luks-$env{ID_FS_UUID}" ENV{ID_FS_TYPE}=="crypto_LUKS", RUN+="/sbin/initqueue /sbin/cryptroot-ask $env{DEVNAME} luks-$env{ID_FS_UUID}"


LABEL="luks_end" LABEL="luks_end"

View File

@ -7,6 +7,6 @@
SUBSYSTEM!="block", GOTO="luks_end" SUBSYSTEM!="block", GOTO="luks_end"
ACTION!="add|change", GOTO="luks_end" ACTION!="add|change", GOTO="luks_end"


ENV{ID_FS_TYPE}=="crypto_LUKS", RUN+="/sbin/cryptroot-ask $env{DEVNAME} luks-$env{ID_FS_UUID}" ENV{ID_FS_TYPE}=="crypto_LUKS", RUN+="/sbin/initqueue /sbin/cryptroot-ask $env{DEVNAME} luks-$env{ID_FS_UUID}"


LABEL="luks_end" LABEL="luks_end"

View File

@ -93,7 +93,7 @@ done
# If we didn't get a root= on the command line, then we need to # If we didn't get a root= on the command line, then we need to
# add the udev rules for mounting the nbd0 device # add the udev rules for mounting the nbd0 device
if [ ! -e /etc/udev/rules.d/99-mount.rules ]; then if [ ! -e /etc/udev/rules.d/99-mount.rules ]; then
printf 'KERNEL=="%s", RUN+="/bin/mount -t %s -o %s %s %s"\n' \ printf 'KERNEL=="%s", RUN+="/sbin/initqueue /bin/mount -t %s -o %s %s %s"\n' \
nbd0 "$nbdfstype" "$fsopts" /dev/nbd0 "$NEWROOT" \ nbd0 "$nbdfstype" "$fsopts" /dev/nbd0 "$NEWROOT" \
> /etc/udev/rules.d/99-mount.rules > /etc/udev/rules.d/99-mount.rules
fi fi

View File

@ -1,8 +1,8 @@
if [ "${root%%:*}" = "block" ]; then if [ "${root%%:*}" = "block" ]; then
( (
printf 'KERNEL=="%s", RUN+="/bin/mount -t %s -o %s %s %s"\n' \ printf 'KERNEL=="%s", RUN+="/sbin/initqueue /bin/mount -t %s -o %s %s %s"\n' \
${root#block:/dev/} "$fstype" "$rflags" "${root#block:}" "$NEWROOT" ${root#block:/dev/} "$fstype" "$rflags" "${root#block:}" "$NEWROOT"
printf 'SYMLINK=="%s", RUN+="/bin/mount -t %s -o %s %s %s"\n' \ printf 'SYMLINK=="%s", RUN+="/sbin/initqueue /bin/mount -t %s -o %s %s %s"\n' \
${root#block:/dev/} "$fstype" "$rflags" "${root#block:}" "$NEWROOT" ${root#block:/dev/} "$fstype" "$rflags" "${root#block:}" "$NEWROOT"
) >> /etc/udev/rules.d/99-mount.rules ) >> /etc/udev/rules.d/99-mount.rules
fi fi

View File

@ -14,6 +14,29 @@ emergency_shell()
sh -i sh -i
} }


do_initqueue()
{
while :; do
# bail out, if we have mounted the root filesystem
[ -d "$NEWROOT/proc" ] && break;

if [ $UDEVVERSION -ge 143 ]; then
udevadm settle --exit-if-exists=/initqueue/work
else
udevadm settle --timeout=30
fi
[ -f /initqueue/work ] || break
rm /initqueue/work
for job in /initqueue/*.job; do
. $job
rm -f $job
# bail out, if we have mounted the root filesystem
[ -d "$NEWROOT/proc" ] && break;
done
done
}

export PATH=/sbin:/bin:/usr/sbin:/usr/bin export PATH=/sbin:/bin:/usr/sbin:/usr/bin
export TERM=linux export TERM=linux
NEWROOT="/sysroot" NEWROOT="/sysroot"
@ -45,6 +68,8 @@ mkdir /dev/shm
mkdir /dev/pts mkdir /dev/pts
mount -t devpts -o gid=5,mode=620 /dev/pts /dev/pts >/dev/null 2>&1 mount -t devpts -o gid=5,mode=620 /dev/pts /dev/pts >/dev/null 2>&1


UDEVVERSION=$(udevadm --version)

# run scriptlets to parse the command line # run scriptlets to parse the command line
getarg 'rdbreak=cmdline' && emergency_shell getarg 'rdbreak=cmdline' && emergency_shell
source_all cmdline source_all cmdline
@ -75,7 +100,8 @@ source_all pre-trigger


# then the rest # then the rest
udevadm trigger $udevtriggeropts >/dev/null 2>&1 udevadm trigger $udevtriggeropts >/dev/null 2>&1
udevadm settle --timeout=30 >/dev/null 2>&1
do_initqueue


# pre-mount happens before we try to mount the root filesystem, # pre-mount happens before we try to mount the root filesystem,
# and happens once. # and happens once.
@ -83,6 +109,8 @@ getarg 'rdbreak=pre-mount' && emergency_shell
source_all pre-mount source_all pre-mount
getarg 'rdbreak=mount' && emergency_shell getarg 'rdbreak=mount' && emergency_shell


do_initqueue

# mount scripts actually try to mount the root filesystem, and may # mount scripts actually try to mount the root filesystem, and may
# be sourced any number of times. As soon as one suceeds, no more are sourced. # be sourced any number of times. As soon as one suceeds, no more are sourced.
i=0 i=0
@ -90,7 +118,8 @@ while :; do
[ -d "$NEWROOT/proc" ] && break; [ -d "$NEWROOT/proc" ] && break;


for f in /mount/*.sh; do for f in /mount/*.sh; do
[ -x "$f" ] && . "$f"; [ -f "$f" ] && . "$f"
do_initqueue
[ "$ROOTFS_MOUNTED" ] && break; [ "$ROOTFS_MOUNTED" ] && break;
done done



5
modules.d/99base/initqueue Executable file
View File

@ -0,0 +1,5 @@
#!/bin/sh

echo "$@" > /tmp/$$.job
mv /tmp/$$.job /initqueue/
>> /initqueue/work

View File

@ -1,11 +1,14 @@
#!/bin/bash #!/bin/bash
dracut_install mount mknod mkdir modprobe pidof sleep chroot sed ls flock cp dracut_install mount mknod mkdir modprobe pidof sleep chroot sed ls flock cp mv
if [ ! -e "${initdir}/bin/sh" ]; then if [ ! -e "${initdir}/bin/sh" ]; then
dracut_install bash dracut_install bash
(ln -s bash "${initdir}/bin/sh" || :) (ln -s bash "${initdir}/bin/sh" || :)
fi fi
# install our scripts and hooks # install our scripts and hooks
inst "$moddir/init" "/init" inst "$moddir/init" "/init"
inst "$moddir/initqueue" "/sbin/initqueue"
mkdir -p ${initdir}/initqueue
mkdir -p ${initdir}/tmp
# Bail out if switch_root does not exist # Bail out if switch_root does not exist
if which switch_root >/dev/null 2>&1; then if which switch_root >/dev/null 2>&1; then
dracut_install switch_root dracut_install switch_root