initqueue now loops until /dev/root exists or root is mounted
authorHarald Hoyer <harald@redhat.com>
Fri, 3 Jul 2009 15:44:10 +0000 (17:44 +0200)
committerHarald Hoyer <harald@redhat.com>
Fri, 3 Jul 2009 16:11:38 +0000 (18:11 +0200)
init now has the following points to inject scripts:

/cmdline/*.sh
   scripts for command line parsing

/pre-udev/*.sh
   scripts to run before udev is started

/pre-trigger/*.sh
   scripts to run before the main udev trigger is pulled

/initqueue/*.sh
   runs in parallel to the udev trigger
   Udev events can add scripts here with /sbin/initqueue.
   If /sbin/initqueue is called with the "--onetime" option, the script
   will be removed after it was run.
   If /initqueue/work is created and udev >= 143 then this loop can
   process the jobs in parallel to the udevtrigger.
   If the udev queue is empty and no root device is found or no root
   filesystem was mounted, the user will be dropped to a shell after
   a timeout.
   Scripts can remove themselves from the initqueue by "rm $job".

/pre-mount/*.sh
   scripts to run before the root filesystem is mounted
   NFS is an exception, because it has no device node to be created
   and mounts in the udev events

/mount/*.sh
   scripts to mount the root filesystem
   NFS is an exception, because it has no device node to be created
   and mounts in the udev events
   If the udev queue is empty and no root device is found or no root
   filesystem was mounted, the user will be dropped to a shell after
   a timeout.

/pre-pivot/*.sh
   scripts to run before the real init is executed and the initramfs
   disappears
   All processes started before should be killed here.

The behaviour of the dmraid module demonstrates how to use the new
mechanism. If it detects a device which is part of a raidmember from a
udev rule, it installs a job to scan for dmraid devices, if the udev
queue is empty. After a scan, it removes itsself from the queue.

12 files changed:
modules.d/50plymouth/63-luks.rules
modules.d/90crypt/70-luks.rules
modules.d/90dmraid/61-dmraid.rules [new file with mode: 0644]
modules.d/90dmraid/dmraid.sh [changed mode: 0644->0755]
modules.d/90dmraid/install
modules.d/95rootfs-block/block-genrules.sh
modules.d/95rootfs-block/install
modules.d/99base/init
modules.d/99base/initqueue
test/TEST-10-RAID/test.sh
test/TEST-30-ISCSI/test.sh
test/TEST-40-NBD/test.sh

index c3c6627aba6ea638581f2d3c705bf30e092d6980..f55bf39685e69b0cd337bd2cd1ba9d2d77d703d8 100644 (file)
@@ -7,6 +7,6 @@
 SUBSYSTEM!="block", GOTO="luks_end"
 ACTION!="add|change", GOTO="luks_end"
 
-ENV{ID_FS_TYPE}=="crypto_LUKS", RUN+="/sbin/initqueue /sbin/cryptroot-ask $env{DEVNAME} luks-$env{ID_FS_UUID}"
+ENV{ID_FS_TYPE}=="crypto_LUKS", RUN+="/sbin/initqueue --onetime /sbin/cryptroot-ask $env{DEVNAME} luks-$env{ID_FS_UUID}"
 
 LABEL="luks_end"
index c3c6627aba6ea638581f2d3c705bf30e092d6980..f55bf39685e69b0cd337bd2cd1ba9d2d77d703d8 100644 (file)
@@ -7,6 +7,6 @@
 SUBSYSTEM!="block", GOTO="luks_end"
 ACTION!="add|change", GOTO="luks_end"
 
-ENV{ID_FS_TYPE}=="crypto_LUKS", RUN+="/sbin/initqueue /sbin/cryptroot-ask $env{DEVNAME} luks-$env{ID_FS_UUID}"
+ENV{ID_FS_TYPE}=="crypto_LUKS", RUN+="/sbin/initqueue --onetime /sbin/cryptroot-ask $env{DEVNAME} luks-$env{ID_FS_UUID}"
 
 LABEL="luks_end"
diff --git a/modules.d/90dmraid/61-dmraid.rules b/modules.d/90dmraid/61-dmraid.rules
new file mode 100644 (file)
index 0000000..661335d
--- /dev/null
@@ -0,0 +1,12 @@
+# This file causes block devices with Linux RAID (mdadm) signatures to
+# automatically cause mdadm to be run.
+# See udev(8) for syntax
+
+SUBSYSTEM!="block", GOTO="dm_end"
+ACTION!="add|change", GOTO="dm_end"
+
+ENV{ID_FS_TYPE}=="linux_raid_member", GOTO="dm_end"
+
+ENV{ID_FS_TYPE}=="*_raid_member", RUN+="/sbin/initqueue /sbin/dmraid_scan \$0"
+
+LABEL="dm_end"
old mode 100644 (file)
new mode 100755 (executable)
index 4e2d5bf..433e5d3
@@ -1,3 +1,8 @@
-dmraid -ay -Z
-udevadm settle --timeout=30 >/dev/null 2>&1 
+#!/bin/sh
+
+if udevadm settle --timeout=0 >/dev/null 2>&1; then
+    # run dmraid if udev has settled
+    dmraid -ay -Z
+    [ -e "$job" ] && rm -f "$job"
+fi
 
index 636f1d2cc866c35b8058323461327f1317d84b6d..3e64a27d902eb3b8d4f0399c0dcfe019da60e602 100755 (executable)
@@ -1,4 +1,5 @@
 #!/bin/bash
 dracut_install dmraid 
-inst_hook pre-mount 10 "$moddir/dmraid.sh"
+inst "$moddir/dmraid.sh" /sbin/dmraid_scan
 inst_rules 64-md-raid.rules
+inst_rules "$moddir/61-dmraid.rules"
index 5d1a669cfe07beeb0e840e2d6ab2085a5deb9cf1..10471ea5ed52b55368dc1cc85ed804b937135537 100644 (file)
@@ -5,4 +5,8 @@ if [ "${root%%:*}" = "block" ]; then
     printf 'SYMLINK=="%s", SYMLINK+="root"\n' \
        ${root#block:/dev/} 
     ) >> /etc/udev/rules.d/99-mount.rules
+    (
+    printf '[ -e "%s" ] && { ln -s "%s" /dev/root; rm "$job"; }\n' \
+       "${root#block:}" "${root#block:}"
+    ) >> /initqueue/blocksymlink.sh
 fi
index 618d357d9483b067c3c88f5c1e38c7b7b79b68c7..d6c161aa995e0d69cf960880d3dbf4c3cbaa268e 100755 (executable)
@@ -1,4 +1,5 @@
 #!/bin/sh
+dracut_install ln
 inst_hook cmdline 95 "$moddir/parse-block.sh"
 inst_hook pre-udev 30 "$moddir/block-genrules.sh"
 inst_hook mount 99 "$moddir/mount-root.sh"
index bb202202f6e756c4ac448f1021bb3a7bc8cc39e9..f082765c10b04337edcb9aae9489d5935c2227e9 100755 (executable)
@@ -16,36 +16,6 @@ emergency_shell()
     sh -i
 }
 
-do_initqueue()
-{
-    while :; do
-        # bail out, if we have mounted the root filesystem
-       [ -d "$NEWROOT/proc" ] && break;
-
-        # check if root can be mounted
-        [ -e /dev/root ] && break;
-
-       if [ $UDEVVERSION -ge 143 ]; then
-           udevadm settle --exit-if-exists=/initqueue/work --exit-if-exists=/dev/root
-       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;
-
-            # check if root can be mounted
-           [ -e /dev/root ] && break;
-       done
-    done
-}
-
 export PATH=/sbin:/bin:/usr/sbin:/usr/bin
 export TERM=linux
 NEWROOT="/sysroot"
@@ -116,7 +86,47 @@ source_all pre-trigger
 # then the rest
 udevadm trigger $udevtriggeropts  >/dev/null 2>&1
 
-do_initqueue
+i=0
+while :; do
+    # bail out, if we have mounted the root filesystem
+    [ -d "$NEWROOT/proc" ] && break;
+
+    # check if root can be mounted
+    [ -e /dev/root ] && break;
+
+    if [ $UDEVVERSION -ge 143 ]; then
+        udevadm settle --exit-if-exists=/initqueue/work --exit-if-exists=/dev/root 
+    else
+        udevadm settle --timeout=30
+    fi
+    unset queuetriggered
+    if [ -f /initqueue/work ]; then
+        rm /initqueue/work
+       queuetriggered="1"
+    fi
+       
+    for job in /initqueue/*.sh; do
+       [ -e "$job" ] || break
+        job=$job . $job
+
+        # bail out, if we have mounted the root filesystem
+        [ -d "$NEWROOT/proc" ] && break;
+        # check if root can be mounted
+        [ -e /dev/root ] && break;
+    done
+
+    [ -n "$queuetriggered" ] && continue
+
+    if udevadm settle --timeout=0 >/dev/null 2>&1; then
+        # no more udev jobs
+        sleep 0.5
+        i=$(($i+1))
+        [ $i -gt 20 ] && getarg rdshell \
+            && { flock -s 9 ; emergency_shell; } 9>/.console_lock
+    fi
+done
+unset job
+unset queuetriggered
 
 # pre-mount happens before we try to mount the root filesystem,
 # and happens once.
@@ -124,23 +134,19 @@ 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
 while :; do
     [ -d "$NEWROOT/proc" ] && break;
-
     for f in /mount/*.sh; do
        [ -f "$f" ] && . "$f"
-       do_initqueue
-       [ "$ROOTFS_MOUNTED" ] && break;
+       [ -d "$NEWROOT/proc" ] && break;
     done
 
-    sleep 0.5
     i=$(($i+1))
-    { flock -s 9 ; [ $i -gt 20 ] && emergency_shell; } 9>/.console_lock
+    [ $i -gt 20 ] && getarg rdshell \
+        && { flock -s 9 ; emergency_shell; } 9>/.console_lock
 done
 
 # pre pivot scripts are sourced just before we switch over to the new root.
index 0a760b724abb38e0247a2e9cd403074959981570..a5c6ef64ad7d9c68fa18689e69c356d12d2df2aa 100755 (executable)
@@ -1,5 +1,12 @@
 #!/bin/sh
 
-echo "$@" > /tmp/$$.job
-mv /tmp/$$.job /initqueue/
+if [ "$1" = "--onetime" ]; then
+    onetime="yes"
+    shift
+fi
+echo "$@" > /tmp/$$.sh
+if [ -n "$onetime" ]; then
+   echo '[ -e "$job" ] && rm "$job"' >> /tmp/$$.sh
+fi
+mv /tmp/$$.sh /initqueue/
 >> /initqueue/work
index 23f9aff5b998a546f3a1d65a76a164a550bb5fec..700c3775b8c10043deaec29c548b3869047275ae 100755 (executable)
@@ -38,7 +38,7 @@ test_setup() {
        initdir=overlay
        . $basedir/dracut-functions
        dracut_install sfdisk mke2fs poweroff cp umount 
-       inst_simple ./create-root.sh /pre-mount/01create-root.sh
+       inst_simple ./create-root.sh /initqueue/01create-root.sh
     )
  
     # create an initramfs that will create the target root filesystem.
index 6469950924c338548135dcb9459180c7217a248e..d9da529d1e83876b8b7d3ab87c36073dbb00f3af 100755 (executable)
@@ -81,7 +81,7 @@ test_setup() {
        initdir=overlay
        . $basedir/dracut-functions
        dracut_install sfdisk mke2fs poweroff cp umount 
-       inst_simple ./create-root.sh /pre-mount/01create-root.sh
+       inst_simple ./create-root.sh /initqueue/01create-root.sh
     )
  
     # create an initramfs that will create the target root filesystem.
index 2f545111252a1aadf576375ea06df09e572ecf3b..07de7fedc8a662dccc6cedebc83dc439c9957895 100755 (executable)
@@ -184,7 +184,7 @@ make_encrypted_root() {
        initdir=overlay
        . $basedir/dracut-functions
        dracut_install mke2fs poweroff cp umount
-       inst_simple ./create-root.sh /pre-mount/01create-root.sh
+       inst_simple ./create-root.sh /initqueue/01create-root.sh
     )
 
     # create an initramfs that will create the target root filesystem.