From: Harald Hoyer Date: Thu, 2 Jul 2009 09:42:35 +0000 (+0200) Subject: switch to initqueue handling of events X-Git-Tag: 0.3~4 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=eab677a2164bccb3990487dc5ef4549b30cb1055;p=platform%2Fupstream%2Fdracut.git 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. --- diff --git a/modules.d/40network/net-genrules.sh b/modules.d/40network/net-genrules.sh index dbd0474..f843c53 100755 --- a/modules.d/40network/net-genrules.sh +++ b/modules.d/40network/net-genrules.sh @@ -19,20 +19,20 @@ fix_bootif() { BOOTIF=$(getarg 'BOOTIF=') if [ -n "$BOOTIF" ] ; then 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. elif [ -n "$IFACES" ] ; then 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 # Default: We don't know the interface to use, handle all 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 # Udev event 'online' only gets fired from ifup/dhclient-script. # 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 diff --git a/modules.d/50plymouth/63-luks.rules b/modules.d/50plymouth/63-luks.rules index cfa619b..c3c6627 100644 --- a/modules.d/50plymouth/63-luks.rules +++ b/modules.d/50plymouth/63-luks.rules @@ -7,6 +7,6 @@ SUBSYSTEM!="block", 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" diff --git a/modules.d/90crypt/70-luks.rules b/modules.d/90crypt/70-luks.rules index cfa619b..c3c6627 100644 --- a/modules.d/90crypt/70-luks.rules +++ b/modules.d/90crypt/70-luks.rules @@ -7,6 +7,6 @@ SUBSYSTEM!="block", 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" diff --git a/modules.d/95nbd/nbdroot b/modules.d/95nbd/nbdroot index 90f6ef8..ad2e906 100755 --- a/modules.d/95nbd/nbdroot +++ b/modules.d/95nbd/nbdroot @@ -93,7 +93,7 @@ done # If we didn't get a root= on the command line, then we need to # add the udev rules for mounting the nbd0 device 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" \ > /etc/udev/rules.d/99-mount.rules fi diff --git a/modules.d/95rootfs-block/block-genrules.sh b/modules.d/95rootfs-block/block-genrules.sh index d6924c8..2706dbb 100644 --- a/modules.d/95rootfs-block/block-genrules.sh +++ b/modules.d/95rootfs-block/block-genrules.sh @@ -1,8 +1,8 @@ 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" - 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" ) >> /etc/udev/rules.d/99-mount.rules fi diff --git a/modules.d/99base/init b/modules.d/99base/init index 868ca19..0e29d76 100755 --- a/modules.d/99base/init +++ b/modules.d/99base/init @@ -14,6 +14,29 @@ emergency_shell() 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 TERM=linux NEWROOT="/sysroot" @@ -45,6 +68,8 @@ mkdir /dev/shm mkdir /dev/pts 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 getarg 'rdbreak=cmdline' && emergency_shell source_all cmdline @@ -75,7 +100,8 @@ source_all pre-trigger # then the rest 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, # and happens once. @@ -83,6 +109,8 @@ getarg 'rdbreak=pre-mount' && emergency_shell source_all pre-mount getarg 'rdbreak=mount' && emergency_shell +do_initqueue + # 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. i=0 @@ -90,7 +118,8 @@ while :; do [ -d "$NEWROOT/proc" ] && break; for f in /mount/*.sh; do - [ -x "$f" ] && . "$f"; + [ -f "$f" ] && . "$f" + do_initqueue [ "$ROOTFS_MOUNTED" ] && break; done diff --git a/modules.d/99base/initqueue b/modules.d/99base/initqueue new file mode 100755 index 0000000..0a760b7 --- /dev/null +++ b/modules.d/99base/initqueue @@ -0,0 +1,5 @@ +#!/bin/sh + +echo "$@" > /tmp/$$.job +mv /tmp/$$.job /initqueue/ +>> /initqueue/work diff --git a/modules.d/99base/install b/modules.d/99base/install index b233f97..ff15200 100755 --- a/modules.d/99base/install +++ b/modules.d/99base/install @@ -1,11 +1,14 @@ #!/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 dracut_install bash (ln -s bash "${initdir}/bin/sh" || :) fi # install our scripts and hooks 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 if which switch_root >/dev/null 2>&1; then dracut_install switch_root