== Hooks
-init has the following hook points to inject scripts:
-
-`/var/lib/dracut/hooks/cmdline/*.sh`::
+Dracut init looks for custom hook scripts in the following locations
+(`HOOKDIR` below): `/var/lib/dracut/hooks`, `/etc/dracut/hooks`, and
+`/lib/dracut/hooks`. The intended use of these locations is: standard,
+distribution shipped scripts are put to `/lib/dracut/hooks`;
+`/etc/dracut/hooks` is used as a local override; dracut modules create
+(and remove) scripts in runtime in `/var/lib/dracut/hooks` (and `$hookdir`
+variable is provided). The following hook points to inject scripts are
+currently supported:
+
+`HOOKDIR/cmdline/*.sh`::
scripts for command line parsing
-`/var/lib/dracut/hooks/pre-udev/*.sh`::
+`HOOKDIR/pre-udev/*.sh`::
scripts to run before udev is started
-`/var/lib/dracut/hooks/pre-trigger/*.sh`::
+`HOOKDIR/pre-trigger/*.sh`::
scripts to run before the main udev trigger is pulled
-`/var/lib/dracut/hooks/initqueue/*.sh`::
+`HOOKDIR/initqueue/*.sh`::
runs in parallel to the udev trigger
+
Udev events can add scripts here with `/sbin/initqueue`.
+
Scripts can remove themselves from the initqueue by `rm $job`.
-`/var/lib/dracut/hooks/pre-mount/*.sh`::
+`HOOKDIR/pre-mount/*.sh`::
scripts to run before the root filesystem is mounted
+
Network filesystems like NFS that do not use device files are an
exception. Root can be mounted already at this point.
-`/var/lib/dracut/hooks/mount/*.sh`::
+`HOOKDIR/mount/*.sh`::
scripts to mount the root filesystem
+
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.
-`/var/lib/dracut/hooks/pre-pivot/*.sh`::
+`HOOKDIR/pre-pivot/*.sh`::
scripts to run before latter initramfs cleanups
-`/var/lib/dracut/hooks/cleanup/*.sh`::
+`HOOKDIR/cleanup/*.sh`::
scripts to run before the real init is executed and the initramfs
disappears
+
}
if [[ "$(ln --help)" == *--relative* ]]; then
+ # shellcheck disable=SC2329
ln_r() {
local dstdir="${dstdir:-"$initdir"}"
ln -sfnr "${dstdir}/$1" "${dstdir}/$2"
}
else
+ # shellcheck disable=SC2329
ln_r() {
local dstdir="${dstdir:-"$initdir"}"
local _source=$1
# shellcheck disable=SC2068
((${#install_optional_items[@]} > 0)) && inst_multiple -o ${install_optional_items[@]}
- # symlink to old hooks location for compatibility
- ln_r /var/lib/dracut/hooks /lib/dracut/hooks
-
for _d in $hookdirs; do
# shellcheck disable=SC2174
mkdir -m 0755 -p "${initdir}/var/lib/dracut/hooks/$_d"
which are sourced by init.
Common used functions are in _dracut-lib.sh_, which can be sourced by any script.
+dracut looks for custom hook scripts in subdirectories (cmdline, pre-udev,
+pre-trigger, initqueue, pre-mount, mount, pre-pivot, cleanup) of the following
+locations: _/var/lib/dracut/hooks_, _/etc/dracut/hooks_, and
+_/lib/dracut/hooks_. The intended use of these locations is: standard,
+distribution shipped scripts are put to _/lib/dracut/hooks_; _/etc/dracut/hooks_
+is used as a local override; dracut modules create (and remove) scripts in
+runtime in _/var/lib/dracut/hooks_. If a hook with the same name exists in
+multiple locations simultaneously, the most privileged location
+(_/var/lib/dracut/hooks_, then _/etc/dracut/hooks_, and then
+_/lib/dracut/hooks_) wins and only one instance of the hook is executed.
+
=== Hook: cmdline
The _cmdline_ hook is a place to insert scripts to parse the kernel command line
ConditionPathExists=/usr/lib/initrd-release
ConditionPathExistsGlob=|/etc/cmdline.d/*.conf
ConditionDirectoryNotEmpty=|/var/lib/dracut/hooks/cmdline
+ConditionDirectoryNotEmpty=|/etc/dracut/hooks/cmdline
+ConditionDirectoryNotEmpty=|/lib/dracut/hooks/cmdline
ConditionKernelCommandLine=|rd.break=cmdline
Conflicts=shutdown.target emergency.target
After=dracut-initqueue.service dracut-pre-mount.service
ConditionPathExists=/usr/lib/initrd-release
ConditionDirectoryNotEmpty=|/var/lib/dracut/hooks/mount
+ConditionDirectoryNotEmpty=|/etc/dracut/hooks/mount
+ConditionDirectoryNotEmpty=|/lib/dracut/hooks/mount
ConditionKernelCommandLine=|rd.break=mount
DefaultDependencies=no
Conflicts=shutdown.target emergency.target
After=dracut-initqueue.service cryptsetup.target
ConditionPathExists=/usr/lib/initrd-release
ConditionDirectoryNotEmpty=|/var/lib/dracut/hooks/pre-mount
+ConditionDirectoryNotEmpty=|/etc/dracut/hooks/pre-mount
+ConditionDirectoryNotEmpty=|/lib/dracut/hooks/pre-mount
ConditionKernelCommandLine=|rd.break=pre-mount
Conflicts=shutdown.target emergency.target
After=remote-fs.target
ConditionPathExists=/usr/lib/initrd-release
ConditionDirectoryNotEmpty=|/var/lib/dracut/hooks/pre-pivot
+ConditionDirectoryNotEmpty=|/etc/dracut/hooks/pre-pivot
+ConditionDirectoryNotEmpty=|/lib/dracut/hooks/pre-pivot
ConditionDirectoryNotEmpty=|/var/lib/dracut/hooks/cleanup
+ConditionDirectoryNotEmpty=|/etc/dracut/hooks/cleanup
+ConditionDirectoryNotEmpty=|/lib/dracut/hooks/cleanup
ConditionKernelCommandLine=|rd.break=pre-pivot
ConditionKernelCommandLine=|rd.break=cleanup
ConditionKernelCommandLine=|rd.break
Wants=dracut-pre-udev.service systemd-udevd.service
ConditionPathExists=/usr/lib/initrd-release
ConditionDirectoryNotEmpty=|/var/lib/dracut/hooks/pre-trigger
+ConditionDirectoryNotEmpty=|/etc/dracut/hooks/pre-trigger
+ConditionDirectoryNotEmpty=|/lib/dracut/hooks/pre-trigger
ConditionKernelCommandLine=|rd.break=pre-trigger
Conflicts=shutdown.target emergency.target
Wants=dracut-cmdline.service
ConditionPathExists=/usr/lib/initrd-release
ConditionDirectoryNotEmpty=|/var/lib/dracut/hooks/pre-udev
+ConditionDirectoryNotEmpty=|/etc/dracut/hooks/pre-udev
+ConditionDirectoryNotEmpty=|/lib/dracut/hooks/pre-udev
ConditionKernelCommandLine=|rd.break=pre-udev
ConditionKernelCommandLine=|rd.driver.blacklist
ConditionKernelCommandLine=|rd.driver.pre
[ -z "$pattern" ] && pattern="*.sh"
local hook
- for hook in "$hookdir/$dir/"$pattern; do
- [ -f "$hook" ] && echo "$hook"
+ # It is allowed to override hooks by creating a file with the same name
+ # in a directory which has higher priority. '/var/lib/dracut/hooks' gets top
+ # priority, '/etc/dracut/hooks' comes after and '/lib/dracut/hooks' is the
+ # least priviliged location.
+ for hook in "/var/lib/dracut/hooks/$dir/"$pattern; do
+ [ -f "$hook" ] && echo "$hook"
+ done
+ for hook in "/etc/dracut/hooks/$dir/"$pattern; do
+ [ -f "$hook" ] && [ ! -f "/var/lib/dracut/hooks/$dir/${hook##*/}" ] && echo "$hook"
+ done
+ for hook in "/lib/dracut/hooks/$dir/"$pattern; do
+ [ -f "$hook" ] && [ ! -f "/var/lib/dracut/hooks/$dir/${hook##*/}" ] \
+ && [ ! -f "/etc/dracut/hooks/$dir/${hook##*/}" ] && echo "$hook"
done
}
mkdir -m 0755 -p "${initdir}"/lib/dracut
mkdir -m 0755 -p "${initdir}"/var/lib/dracut/hooks
- # symlink to old hooks location for compatibility
- ln_r /var/lib/dracut/hooks /lib/dracut/hooks
-
mkdir -p "${initdir}"/tmp
inst_simple "$moddir/dracut-lib.sh" "/lib/dracut-lib.sh"
inst "$moddir/shutdown.sh" "$prefix/shutdown"
mkdir -m 0755 -p "${initdir}"/var/lib/dracut/hooks
- # symlink to old hooks location for compatibility
- ln_r /var/lib/dracut/hooks /lib/dracut/hooks
-
for _d in $hookdirs shutdown shutdown-emergency; do
mkdir -m 0755 -p "${initdir}"/var/lib/dracut/hooks/"$_d"
done