diff options
Diffstat (limited to 'modules.d/98dracut-systemd')
33 files changed, 1154 insertions, 0 deletions
diff --git a/modules.d/98dracut-systemd/dracut-cmdline-ask.service b/modules.d/98dracut-systemd/dracut-cmdline-ask.service new file mode 100644 index 0000000..c9458b7 --- /dev/null +++ b/modules.d/98dracut-systemd/dracut-cmdline-ask.service @@ -0,0 +1,32 @@ +# This file is part of dracut. + +[Unit] +Description=dracut ask for additional cmdline parameters +Documentation=man:dracut.bootup(7) +DefaultDependencies=no +Before=dracut-cmdline.service +Wants=systemd-journald.socket +After=systemd-journald.socket +Wants=systemd-vconsole-setup.service +After=systemd-vconsole-setup.service + +ConditionPathExists=/usr/lib/initrd-release +ConditionKernelCommandLine=|rd.cmdline=ask +ConditionPathExistsGlob=|/etc/cmdline.d/*.conf +Conflicts=shutdown.target emergency.target + +[Service] +Environment=DRACUT_SYSTEMD=1 +Environment=NEWROOT=/sysroot +Type=oneshot +ExecStart=-/bin/dracut-cmdline-ask +StandardInput=tty +StandardOutput=inherit +StandardError=inherit +RemainAfterExit=yes +KillMode=process +IgnoreSIGPIPE=no + +# Bash ignores SIGTERM, so we send SIGHUP instead, to ensure that bash +# terminates cleanly. +KillSignal=SIGHUP diff --git a/modules.d/98dracut-systemd/dracut-cmdline-ask.sh b/modules.d/98dracut-systemd/dracut-cmdline-ask.sh new file mode 100755 index 0000000..13c4f20 --- /dev/null +++ b/modules.d/98dracut-systemd/dracut-cmdline-ask.sh @@ -0,0 +1,22 @@ +#!/bin/sh + +type getarg > /dev/null 2>&1 || . /lib/dracut-lib.sh + +getarg "rd.cmdline=ask" || exit 0 + +sleep 0.5 +echo +sleep 0.5 +echo +sleep 0.5 +echo +echo +echo +echo +echo "Enter additional kernel command line parameter (end with ctrl-d or .)" +while read -r -p "> " ${BASH:+-e} line || [ -n "$line" ]; do + [ "$line" = "." ] && break + [ -n "$line" ] && printf -- "%s\n" "$line" >> /etc/cmdline.d/99-cmdline-ask.conf +done + +exit 0 diff --git a/modules.d/98dracut-systemd/dracut-cmdline.service b/modules.d/98dracut-systemd/dracut-cmdline.service new file mode 100644 index 0000000..ed71d58 --- /dev/null +++ b/modules.d/98dracut-systemd/dracut-cmdline.service @@ -0,0 +1,30 @@ +# This file is part of dracut. + +[Unit] +Description=dracut cmdline hook +Documentation=man:dracut-cmdline.service(8) man:dracut.bootup(7) +DefaultDependencies=no +Before=dracut-pre-udev.service +After=systemd-journald.socket +Wants=systemd-journald.socket +ConditionPathExists=/usr/lib/initrd-release +ConditionPathExistsGlob=|/etc/cmdline.d/*.conf +ConditionDirectoryNotEmpty=|/lib/dracut/hooks/cmdline +ConditionKernelCommandLine=|rd.break=cmdline +ConditionKernelCommandLine=|resume +ConditionKernelCommandLine=|noresume +Conflicts=shutdown.target emergency.target + +[Service] +Environment=DRACUT_SYSTEMD=1 +Environment=NEWROOT=/sysroot +Type=oneshot +ExecStart=-/bin/dracut-cmdline +StandardInput=null +StandardError=journal+console +KillMode=process +RemainAfterExit=yes + +# Bash ignores SIGTERM, so we send SIGHUP instead, to ensure that bash +# terminates cleanly. +KillSignal=SIGHUP diff --git a/modules.d/98dracut-systemd/dracut-cmdline.service.8.asc b/modules.d/98dracut-systemd/dracut-cmdline.service.8.asc new file mode 100644 index 0000000..859448e --- /dev/null +++ b/modules.d/98dracut-systemd/dracut-cmdline.service.8.asc @@ -0,0 +1,26 @@ +DRACUT-CMDLINE.SERVICE(8) +========================= +:doctype: manpage +:man source: dracut +:man manual: dracut + +NAME +---- +dracut-cmdline.service - runs the dracut hooks to parse the kernel command line + +SYNOPSIS +-------- +dracut-cmdline.service + +DESCRIPTION +----------- +This service runs all the dracut hooks to parse the kernel command line in +the initramfs. + +AUTHORS +------- +Harald Hoyer + +SEE ALSO +-------- +*dracut.bootup*(7) *dracut*(8) diff --git a/modules.d/98dracut-systemd/dracut-cmdline.sh b/modules.d/98dracut-systemd/dracut-cmdline.sh new file mode 100755 index 0000000..646fead --- /dev/null +++ b/modules.d/98dracut-systemd/dracut-cmdline.sh @@ -0,0 +1,75 @@ +#!/bin/sh + +if [ -f /dracut-state.sh ]; then + . /dracut-state.sh 2> /dev/null +fi +type getarg > /dev/null 2>&1 || . /lib/dracut-lib.sh + +[ -f /usr/lib/initrd-release ] && . /usr/lib/initrd-release +[ -n "$VERSION" ] && info "dracut-$VERSION" + +if ! getargbool 1 'rd.hostonly'; then + [ -f /etc/cmdline.d/99-cmdline-ask.conf ] && mv /etc/cmdline.d/99-cmdline-ask.conf /tmp/99-cmdline-ask.conf + remove_hostonly_files + systemctl --no-block daemon-reload + [ -f /tmp/99-cmdline-ask.conf ] && mv /tmp/99-cmdline-ask.conf /etc/cmdline.d/99-cmdline-ask.conf +fi + +info "Using kernel command line parameters:" "$(getcmdline)" + +getargbool 0 rd.udev.log-priority=info -d rd.udev.info -d -n -y rdudevinfo && echo 'udev_log="info"' >> /etc/udev/udev.conf +getargbool 0 rd.udev.log-priority=debug -d rd.udev.debug -d -n -y rdudevdebug && echo 'udev_log="debug"' >> /etc/udev/udev.conf + +source_conf /etc/conf.d + +# Get the "root=" parameter from the kernel command line, but differentiate +# between the case where it was set to the empty string and the case where it +# wasn't specified at all. +if ! root="$(getarg root=)"; then + root_unset='UNSET' +fi + +rflags="$(getarg rootflags=)" +getargbool 0 ro && rflags="${rflags},ro" +getargbool 0 rw && rflags="${rflags},rw" +rflags="${rflags#,}" + +fstype="$(getarg rootfstype=)" +if [ -z "$fstype" ]; then + fstype="auto" +fi + +export root +export rflags +export fstype + +make_trace_mem "hook cmdline" '1+:mem' '1+:iomem' '3+:slab' +# run scriptlets to parse the command line +getarg 'rd.break=cmdline' -d 'rdbreak=cmdline' && emergency_shell -n cmdline "Break before cmdline" +source_hook cmdline + +[ -f /lib/dracut/parse-resume.sh ] && . /lib/dracut/parse-resume.sh + +case "${root#block:}${root_unset}" in + LABEL=* | UUID=* | PARTUUID=* | PARTLABEL=*) + root="block:$(label_uuid_to_dev "${root#block:}")" + rootok=1 + ;; + /dev/*) + root="block:${root#block:}" + rootok=1 + ;; + UNSET | gpt-auto | tmpfs) + # systemd's gpt-auto-generator/fstab-generator handles this case. + rootok=1 + ;; +esac + +[ -z "${root}${root_unset}" ] && die "Empty root= argument" +[ -z "$rootok" ] && die "Don't know how to handle 'root=$root'" + +export root rflags fstype netroot NEWROOT + +export -p > /dracut-state.sh + +exit 0 diff --git a/modules.d/98dracut-systemd/dracut-emergency.service b/modules.d/98dracut-systemd/dracut-emergency.service new file mode 100644 index 0000000..eb3e67f --- /dev/null +++ b/modules.d/98dracut-systemd/dracut-emergency.service @@ -0,0 +1,28 @@ +# This file is part of dracut. + +[Unit] +Description=Dracut Emergency Shell +Documentation=man:dracut.bootup(7) +DefaultDependencies=no +After=systemd-vconsole-setup.service +Wants=systemd-vconsole-setup.service +Conflicts=shutdown.target emergency.target + +[Service] +Environment=HOME=/ +Environment=DRACUT_SYSTEMD=1 +Environment=NEWROOT=/sysroot +WorkingDirectory=/ +ExecStart=-/bin/dracut-emergency +ExecStopPost=-/bin/rm -f -- /.console_lock +Type=oneshot +StandardInput=tty-force +StandardOutput=inherit +StandardError=inherit +KillMode=process +IgnoreSIGPIPE=no +TasksMax=infinity + +# Bash ignores SIGTERM, so we send SIGHUP instead, to ensure that bash +# terminates cleanly. +KillSignal=SIGHUP diff --git a/modules.d/98dracut-systemd/dracut-emergency.sh b/modules.d/98dracut-systemd/dracut-emergency.sh new file mode 100755 index 0000000..c6637a5 --- /dev/null +++ b/modules.d/98dracut-systemd/dracut-emergency.sh @@ -0,0 +1,59 @@ +#!/bin/sh + +export DRACUT_SYSTEMD=1 +if [ -f /dracut-state.sh ]; then + . /dracut-state.sh 2> /dev/null +fi +type getarg > /dev/null 2>&1 || . /lib/dracut-lib.sh + +source_conf /etc/conf.d + +type plymouth > /dev/null 2>&1 && plymouth quit + +export _rdshell_name="dracut" action="Boot" hook="emergency" +_emergency_action=$(getarg rd.emergency) + +if getargbool 1 rd.shell -d -y rdshell || getarg rd.break -d rdbreak; then + FSTXT="/run/dracut/fsck/fsck_help_$fstype.txt" + RDSOSREPORT="$(rdsosreport)" + source_hook "$hook" + while read -r _tty rest; do + ( + echo + echo "$RDSOSREPORT" + echo + echo + echo 'Entering emergency mode. Exit the shell to continue.' + echo 'Type "journalctl" to view system logs.' + echo 'You might want to save "/run/initramfs/rdsosreport.txt" to a USB stick or /boot' + echo 'after mounting them and attach it to a bug report.' + echo + echo + [ -f "$FSTXT" ] && cat "$FSTXT" + ) > /dev/"$_tty" + done < /proc/consoles + [ -f /etc/profile ] && . /etc/profile + [ -z "$PS1" ] && export PS1="$_name:\${PWD}# " + exec sulogin -e +else + export hook="shutdown-emergency" + warn "$action has failed. To debug this issue add \"rd.shell rd.debug\" to the kernel command line." + source_hook "$hook" + [ -z "$_emergency_action" ] && _emergency_action=halt +fi + +/bin/rm -f -- /.console_lock + +case "$_emergency_action" in + reboot) + reboot || exit 1 + ;; + poweroff) + poweroff || exit 1 + ;; + halt) + halt || exit 1 + ;; +esac + +exit 0 diff --git a/modules.d/98dracut-systemd/dracut-initqueue.service b/modules.d/98dracut-systemd/dracut-initqueue.service new file mode 100644 index 0000000..4cd32eb --- /dev/null +++ b/modules.d/98dracut-systemd/dracut-initqueue.service @@ -0,0 +1,28 @@ +# This file is part of dracut. + +[Unit] +Description=dracut initqueue hook +Documentation=man:dracut-initqueue.service(8) man:dracut.bootup(7) +DefaultDependencies=no +Before=remote-fs-pre.target +Wants=remote-fs-pre.target +After=systemd-udev-trigger.service +Wants=systemd-udev-trigger.service +ConditionPathExists=/usr/lib/initrd-release +ConditionPathExists=|/lib/dracut/need-initqueue +ConditionKernelCommandLine=|rd.break=initqueue +Conflicts=shutdown.target emergency.target + +[Service] +Environment=DRACUT_SYSTEMD=1 +Environment=NEWROOT=/sysroot +Type=oneshot +ExecStart=-/bin/dracut-initqueue +StandardInput=null +StandardError=journal+console +KillMode=process +RemainAfterExit=yes + +# Bash ignores SIGTERM, so we send SIGHUP instead, to ensure that bash +# terminates cleanly. +KillSignal=SIGHUP diff --git a/modules.d/98dracut-systemd/dracut-initqueue.service.8.asc b/modules.d/98dracut-systemd/dracut-initqueue.service.8.asc new file mode 100644 index 0000000..66f2d33 --- /dev/null +++ b/modules.d/98dracut-systemd/dracut-initqueue.service.8.asc @@ -0,0 +1,25 @@ +DRACUT-INITQUEUE.SERVICE(8) +=========================== +:doctype: manpage +:man source: dracut +:man manual: dracut + +NAME +---- +dracut-initqueue.service - runs the dracut main loop to find the real root + +SYNOPSIS +-------- +dracut-initqueue.service + +DESCRIPTION +----------- +This service runs all the main loop of dracut in the initramfs to find the real root. + +AUTHORS +------- +Harald Hoyer + +SEE ALSO +-------- +*dracut.bootup*(7) *dracut*(8) diff --git a/modules.d/98dracut-systemd/dracut-initqueue.sh b/modules.d/98dracut-systemd/dracut-initqueue.sh new file mode 100755 index 0000000..ce919ce --- /dev/null +++ b/modules.d/98dracut-systemd/dracut-initqueue.sh @@ -0,0 +1,95 @@ +#!/bin/sh + +export DRACUT_SYSTEMD=1 +if [ -f /dracut-state.sh ]; then + . /dracut-state.sh 2> /dev/null +fi +type getarg > /dev/null 2>&1 || . /lib/dracut-lib.sh + +source_conf /etc/conf.d + +make_trace_mem "hook initqueue" '1:shortmem' '2+:mem' '3+:slab' +getarg 'rd.break=initqueue' -d 'rdbreak=initqueue' && emergency_shell -n initqueue "Break before initqueue" + +RDRETRY=$(getarg rd.retry -d 'rd_retry=') +RDRETRY=${RDRETRY:-180} +RDRETRY=$((RDRETRY * 2)) +export RDRETRY + +main_loop=0 +export main_loop + +while :; do + + check_finished && break + + udevadm settle --exit-if-exists="$hookdir"/initqueue/work + + check_finished && break + + if [ -f "$hookdir"/initqueue/work ]; then + rm -f -- "$hookdir/initqueue/work" + fi + + for job in "$hookdir"/initqueue/*.sh; do + [ -e "$job" ] || break + # shellcheck disable=SC2097 disable=SC1090 disable=SC2098 + job=$job . "$job" + check_finished && break 2 + done + + udevadm settle --timeout=0 > /dev/null 2>&1 || continue + + for job in "$hookdir"/initqueue/settled/*.sh; do + [ -e "$job" ] || break + # shellcheck disable=SC2097 disable=SC1090 disable=SC2098 + job=$job . "$job" + check_finished && break 2 + done + + udevadm settle --timeout=0 > /dev/null 2>&1 || continue + + # no more udev jobs and queues empty. + sleep 0.5 + + for i in /run/systemd/ask-password/ask.*; do + [ -e "$i" ] && continue 2 + done + + if [ $main_loop -gt $((2 * RDRETRY / 3)) ]; then + warn "dracut-initqueue: timeout, still waiting for following initqueue hooks:" + for _f in "$hookdir"/initqueue/finished/*.sh; do + warn "$_f: \"$(cat "$_f")\"" + done + if [ "$(ls -A "$hookdir"/initqueue/finished)" ]; then + warn "dracut-initqueue: starting timeout scripts" + for job in "$hookdir"/initqueue/timeout/*.sh; do + [ -e "$job" ] || break + # shellcheck disable=SC2097 disable=SC1090 disable=SC2098 + job=$job . "$job" + udevadm settle --timeout=0 > /dev/null 2>&1 || main_loop=0 + [ -f "$hookdir"/initqueue/work ] && main_loop=0 + [ $main_loop -eq 0 ] && break + done + fi + fi + + main_loop=$((main_loop + 1)) + if [ $main_loop -gt $RDRETRY ]; then + if ! [ -f /sysroot/etc/fstab ] || ! [ -e /sysroot/sbin/init ]; then + emergency_shell "Could not boot." + fi + warn "Not all disks have been found." + warn "You might want to regenerate your initramfs." + break + fi +done + +unset job +unset queuetriggered +unset main_loop +unset RDRETRY + +export -p > /dracut-state.sh + +exit 0 diff --git a/modules.d/98dracut-systemd/dracut-mount.service b/modules.d/98dracut-systemd/dracut-mount.service new file mode 100644 index 0000000..27fff82 --- /dev/null +++ b/modules.d/98dracut-systemd/dracut-mount.service @@ -0,0 +1,26 @@ +# This file is part of dracut. + +[Unit] +Description=dracut mount hook +Documentation=man:dracut-mount.service(8) man:dracut.bootup(7) +After=initrd-root-fs.target initrd-parse-etc.service +After=dracut-initqueue.service dracut-pre-mount.service +ConditionPathExists=/usr/lib/initrd-release +ConditionDirectoryNotEmpty=|/lib/dracut/hooks/mount +ConditionKernelCommandLine=|rd.break=mount +DefaultDependencies=no +Conflicts=shutdown.target emergency.target + +[Service] +Environment=DRACUT_SYSTEMD=1 +Environment=NEWROOT=/sysroot +Type=oneshot +ExecStart=-/bin/dracut-mount +StandardInput=null +StandardError=journal+console +KillMode=process +RemainAfterExit=yes + +# Bash ignores SIGTERM, so we send SIGHUP instead, to ensure that bash +# terminates cleanly. +KillSignal=SIGHUP diff --git a/modules.d/98dracut-systemd/dracut-mount.service.8.asc b/modules.d/98dracut-systemd/dracut-mount.service.8.asc new file mode 100644 index 0000000..969123f --- /dev/null +++ b/modules.d/98dracut-systemd/dracut-mount.service.8.asc @@ -0,0 +1,25 @@ +DRACUT-MOUNT.SERVICE(8) +======================= +:doctype: manpage +:man source: dracut +:man manual: dracut + +NAME +---- +dracut-mount.service - runs the dracut hooks after /sysroot is mounted + +SYNOPSIS +-------- +dracut-mount.service + +DESCRIPTION +----------- +This service runs all dracut hooks after the real root is mounted on /sysroot. + +AUTHORS +------- +Harald Hoyer + +SEE ALSO +-------- +*dracut.bootup*(7) *dracut*(8) diff --git a/modules.d/98dracut-systemd/dracut-mount.sh b/modules.d/98dracut-systemd/dracut-mount.sh new file mode 100755 index 0000000..7892941 --- /dev/null +++ b/modules.d/98dracut-systemd/dracut-mount.sh @@ -0,0 +1,38 @@ +#!/bin/sh +export DRACUT_SYSTEMD=1 +if [ -f /dracut-state.sh ]; then + . /dracut-state.sh 2> /dev/null +fi +type getarg > /dev/null 2>&1 || . /lib/dracut-lib.sh + +source_conf /etc/conf.d + +make_trace_mem "hook mount" '1:shortmem' '2+:mem' '3+:slab' + +getarg 'rd.break=mount' -d 'rdbreak=mount' && emergency_shell -n mount "Break before mount" +# mount scripts actually try to mount the root filesystem, and may +# be sourced any number of times. As soon as one succeeds, no more are sourced. +i=0 +while :; do + if ismounted "$NEWROOT"; then + usable_root "$NEWROOT" && break + umount "$NEWROOT" + fi + for f in "$hookdir"/mount/*.sh; do + # shellcheck disable=SC1090 + [ -f "$f" ] && . "$f" + if ismounted "$NEWROOT"; then + usable_root "$NEWROOT" && break + warn "$NEWROOT has no proper rootfs layout, ignoring and removing offending mount hook" + umount "$NEWROOT" + rm -f -- "$f" + fi + done + + i=$((i + 1)) + [ $i -gt 20 ] && emergency_shell "Can't mount root filesystem" +done + +export -p > /dracut-state.sh + +exit 0 diff --git a/modules.d/98dracut-systemd/dracut-pre-mount.service b/modules.d/98dracut-systemd/dracut-pre-mount.service new file mode 100644 index 0000000..351370b --- /dev/null +++ b/modules.d/98dracut-systemd/dracut-pre-mount.service @@ -0,0 +1,26 @@ +# This file is part of dracut. + +[Unit] +Description=dracut pre-mount hook +Documentation=man:dracut-pre-mount.service(8) man:dracut.bootup(7) +DefaultDependencies=no +Before=initrd-root-fs.target sysroot.mount systemd-fsck-root.service +After=dracut-initqueue.service cryptsetup.target +ConditionPathExists=/usr/lib/initrd-release +ConditionDirectoryNotEmpty=|/lib/dracut/hooks/pre-mount +ConditionKernelCommandLine=|rd.break=pre-mount +Conflicts=shutdown.target emergency.target + +[Service] +Environment=DRACUT_SYSTEMD=1 +Environment=NEWROOT=/sysroot +Type=oneshot +ExecStart=-/bin/dracut-pre-mount +StandardInput=null +StandardError=journal+console +KillMode=process +RemainAfterExit=yes + +# Bash ignores SIGTERM, so we send SIGHUP instead, to ensure that bash +# terminates cleanly. +KillSignal=SIGHUP diff --git a/modules.d/98dracut-systemd/dracut-pre-mount.service.8.asc b/modules.d/98dracut-systemd/dracut-pre-mount.service.8.asc new file mode 100644 index 0000000..9aa671a --- /dev/null +++ b/modules.d/98dracut-systemd/dracut-pre-mount.service.8.asc @@ -0,0 +1,25 @@ +DRACUT-PRE-MOUNT.SERVICE(8) +=========================== +:doctype: manpage +:man source: dracut +:man manual: dracut + +NAME +---- +dracut-pre-mount.service - runs the dracut hooks before /sysroot is mounted + +SYNOPSIS +-------- +dracut-pre-mount.service + +DESCRIPTION +----------- +This service runs all dracut hooks before the real root is mounted on /sysroot. + +AUTHORS +------- +Harald Hoyer + +SEE ALSO +-------- +*dracut.bootup*(7) *dracut*(8) diff --git a/modules.d/98dracut-systemd/dracut-pre-mount.sh b/modules.d/98dracut-systemd/dracut-pre-mount.sh new file mode 100755 index 0000000..ee51605 --- /dev/null +++ b/modules.d/98dracut-systemd/dracut-pre-mount.sh @@ -0,0 +1,19 @@ +#!/bin/sh + +export DRACUT_SYSTEMD=1 +if [ -f /dracut-state.sh ]; then + . /dracut-state.sh 2> /dev/null +fi +type getarg > /dev/null 2>&1 || . /lib/dracut-lib.sh + +source_conf /etc/conf.d + +make_trace_mem "hook pre-mount" '1:shortmem' '2+:mem' '3+:slab' +# pre pivot scripts are sourced just before we doing cleanup and switch over +# to the new root. +getarg 'rd.break=pre-mount' 'rdbreak=pre-mount' && emergency_shell -n pre-mount "Break before pre-mount" +source_hook pre-mount + +export -p > /dracut-state.sh + +exit 0 diff --git a/modules.d/98dracut-systemd/dracut-pre-pivot.service b/modules.d/98dracut-systemd/dracut-pre-pivot.service new file mode 100644 index 0000000..04a3705 --- /dev/null +++ b/modules.d/98dracut-systemd/dracut-pre-pivot.service @@ -0,0 +1,35 @@ +# This file is part of dracut. + +[Unit] +Description=dracut pre-pivot and cleanup hook +Documentation=man:dracut-pre-pivot.service(8) man:dracut.bootup(7) +DefaultDependencies=no +After=initrd.target initrd-parse-etc.service sysroot.mount +After=dracut-initqueue.service dracut-pre-mount.service dracut-mount.service +Before=initrd-cleanup.service +Wants=remote-fs.target +After=remote-fs.target +ConditionPathExists=/usr/lib/initrd-release +ConditionDirectoryNotEmpty=|/lib/dracut/hooks/pre-pivot +ConditionDirectoryNotEmpty=|/lib/dracut/hooks/cleanup +ConditionKernelCommandLine=|rd.break=pre-pivot +ConditionKernelCommandLine=|rd.break=cleanup +ConditionKernelCommandLine=|rd.break +ConditionPathExists=|/dev/root +ConditionPathExists=|/dev/nfs +Conflicts=shutdown.target emergency.target + +[Service] +Environment=DRACUT_SYSTEMD=1 +Environment=NEWROOT=/sysroot +Type=oneshot +ExecStart=-/bin/dracut-pre-pivot +StandardInput=null +StandardError=journal+console +KillMode=process +RemainAfterExit=yes +KeyringMode=shared + +# Bash ignores SIGTERM, so we send SIGHUP instead, to ensure that bash +# terminates cleanly. +KillSignal=SIGHUP diff --git a/modules.d/98dracut-systemd/dracut-pre-pivot.service.8.asc b/modules.d/98dracut-systemd/dracut-pre-pivot.service.8.asc new file mode 100644 index 0000000..df500ac --- /dev/null +++ b/modules.d/98dracut-systemd/dracut-pre-pivot.service.8.asc @@ -0,0 +1,25 @@ +DRACUT-PRE-PIVOT.SERVICE(8) +=========================== +:doctype: manpage +:man source: dracut +:man manual: dracut + +NAME +---- +dracut-pre-pivot.service - runs the dracut hooks before switching root + +SYNOPSIS +-------- +dracut-pre-pivot.service + +DESCRIPTION +----------- +This service runs all dracut hooks before the system switched to the real root. + +AUTHORS +------- +Harald Hoyer + +SEE ALSO +-------- +*dracut.bootup*(7) *dracut*(8) diff --git a/modules.d/98dracut-systemd/dracut-pre-pivot.sh b/modules.d/98dracut-systemd/dracut-pre-pivot.sh new file mode 100755 index 0000000..8bf2325 --- /dev/null +++ b/modules.d/98dracut-systemd/dracut-pre-pivot.sh @@ -0,0 +1,29 @@ +#!/bin/sh + +export DRACUT_SYSTEMD=1 +if [ -f /dracut-state.sh ]; then + . /dracut-state.sh 2> /dev/null +fi +type getarg > /dev/null 2>&1 || . /lib/dracut-lib.sh + +source_conf /etc/conf.d + +make_trace_mem "hook pre-pivot" '1:shortmem' '2+:mem' '3+:slab' +# pre pivot scripts are sourced just before we doing cleanup and switch over +# to the new root. +getarg 'rd.break=pre-pivot' 'rdbreak=pre-pivot' && emergency_shell -n pre-pivot "Break before pre-pivot" +source_hook pre-pivot + +# pre pivot cleanup scripts are sourced just before we switch over to the new root. +getarg 'rd.break=cleanup' 'rdbreak=cleanup' && emergency_shell -n cleanup "Break before cleanup" +source_hook cleanup + +_bv=$(getarg rd.break -d rdbreak) && [ -z "$_bv" ] \ + && emergency_shell -n switch_root "Break before switch_root" +unset _bv + +# remove helper symlink +[ -h /dev/root ] && rm -f -- /dev/root +[ -h /dev/nfs ] && rm -f -- /dev/nfs + +exit 0 diff --git a/modules.d/98dracut-systemd/dracut-pre-trigger.service b/modules.d/98dracut-systemd/dracut-pre-trigger.service new file mode 100644 index 0000000..374cd3a --- /dev/null +++ b/modules.d/98dracut-systemd/dracut-pre-trigger.service @@ -0,0 +1,27 @@ +# This file is part of dracut. + +[Unit] +Description=dracut pre-trigger hook +Documentation=man:dracut-pre-trigger.service(8) man:dracut.bootup(7) +DefaultDependencies=no +Before=systemd-udev-trigger.service dracut-initqueue.service +After=dracut-pre-udev.service systemd-udevd.service systemd-tmpfiles-setup-dev.service +Wants=dracut-pre-udev.service systemd-udevd.service +ConditionPathExists=/usr/lib/initrd-release +ConditionDirectoryNotEmpty=|/lib/dracut/hooks/pre-trigger +ConditionKernelCommandLine=|rd.break=pre-trigger +Conflicts=shutdown.target emergency.target + +[Service] +Environment=DRACUT_SYSTEMD=1 +Environment=NEWROOT=/sysroot +Type=oneshot +ExecStart=-/bin/dracut-pre-trigger +StandardInput=null +StandardError=journal+console +KillMode=process +RemainAfterExit=yes + +# Bash ignores SIGTERM, so we send SIGHUP instead, to ensure that bash +# terminates cleanly. +KillSignal=SIGHUP diff --git a/modules.d/98dracut-systemd/dracut-pre-trigger.service.8.asc b/modules.d/98dracut-systemd/dracut-pre-trigger.service.8.asc new file mode 100644 index 0000000..5b0cc7f --- /dev/null +++ b/modules.d/98dracut-systemd/dracut-pre-trigger.service.8.asc @@ -0,0 +1,25 @@ +DRACUT-PRE-TRIGGER.SERVICE(8) +============================= +:doctype: manpage +:man source: dracut +:man manual: dracut + +NAME +---- +dracut-pre-trigger.service - runs the dracut hooks before udevd is triggered + +SYNOPSIS +-------- +dracut-pre-trigger.service + +DESCRIPTION +----------- +This service runs all dracut hooks before udevd is triggered in the initramfs. + +AUTHORS +------- +Harald Hoyer + +SEE ALSO +-------- +*dracut.bootup*(7) *dracut*(8) diff --git a/modules.d/98dracut-systemd/dracut-pre-trigger.sh b/modules.d/98dracut-systemd/dracut-pre-trigger.sh new file mode 100755 index 0000000..dd0215e --- /dev/null +++ b/modules.d/98dracut-systemd/dracut-pre-trigger.sh @@ -0,0 +1,21 @@ +#!/bin/sh + +export DRACUT_SYSTEMD=1 +if [ -f /dracut-state.sh ]; then + . /dracut-state.sh 2> /dev/null +fi +type getarg > /dev/null 2>&1 || . /lib/dracut-lib.sh + +source_conf /etc/conf.d + +make_trace_mem "hook pre-trigger" '1:shortmem' '2+:mem' '3+:slab' + +source_hook pre-trigger + +getarg 'rd.break=pre-trigger' 'rdbreak=pre-trigger' && emergency_shell -n pre-trigger "Break before pre-trigger" + +udevadm control --reload > /dev/null 2>&1 || : + +export -p > /dracut-state.sh + +exit 0 diff --git a/modules.d/98dracut-systemd/dracut-pre-udev.service b/modules.d/98dracut-systemd/dracut-pre-udev.service new file mode 100644 index 0000000..a61e9d4 --- /dev/null +++ b/modules.d/98dracut-systemd/dracut-pre-udev.service @@ -0,0 +1,31 @@ +# This file is part of dracut. + +[Unit] +Description=dracut pre-udev hook +Documentation=man:dracut-pre-udev.service(8) man:dracut.bootup(7) +DefaultDependencies=no +Before=systemd-udevd.service dracut-pre-trigger.service +After=dracut-cmdline.service +Wants=dracut-cmdline.service +ConditionPathExists=/usr/lib/initrd-release +ConditionDirectoryNotEmpty=|/lib/dracut/hooks/pre-udev +ConditionKernelCommandLine=|rd.break=pre-udev +ConditionKernelCommandLine=|rd.driver.blacklist +ConditionKernelCommandLine=|rd.driver.pre +ConditionKernelCommandLine=|rd.driver.post +ConditionPathExistsGlob=|/etc/cmdline.d/*.conf +Conflicts=shutdown.target emergency.target + +[Service] +Environment=DRACUT_SYSTEMD=1 +Environment=NEWROOT=/sysroot +Type=oneshot +ExecStart=-/bin/dracut-pre-udev +StandardInput=null +StandardError=journal+console +KillMode=process +RemainAfterExit=yes + +# Bash ignores SIGTERM, so we send SIGHUP instead, to ensure that bash +# terminates cleanly. +KillSignal=SIGHUP diff --git a/modules.d/98dracut-systemd/dracut-pre-udev.service.8.asc b/modules.d/98dracut-systemd/dracut-pre-udev.service.8.asc new file mode 100644 index 0000000..c91c8e2 --- /dev/null +++ b/modules.d/98dracut-systemd/dracut-pre-udev.service.8.asc @@ -0,0 +1,25 @@ +DRACUT-PRE-UDEV.SERVICE(8) +========================== +:doctype: manpage +:man source: dracut +:man manual: dracut + +NAME +---- +dracut-pre-udev.service - runs the dracut hooks before udevd is started + +SYNOPSIS +-------- +dracut-pre-udev.service + +DESCRIPTION +----------- +This service runs all dracut hooks before udevd is started in the initramfs. + +AUTHORS +------- +Harald Hoyer + +SEE ALSO +-------- +*dracut.bootup*(7) *dracut*(8) diff --git a/modules.d/98dracut-systemd/dracut-pre-udev.sh b/modules.d/98dracut-systemd/dracut-pre-udev.sh new file mode 100755 index 0000000..feab32c --- /dev/null +++ b/modules.d/98dracut-systemd/dracut-pre-udev.sh @@ -0,0 +1,55 @@ +#!/bin/sh +export DRACUT_SYSTEMD=1 +if [ -f /dracut-state.sh ]; then + . /dracut-state.sh 2> /dev/null +fi +type getarg > /dev/null 2>&1 || . /lib/dracut-lib.sh + +source_conf /etc/conf.d + +make_trace_mem "hook pre-udev" '1:shortmem' '2+:mem' '3+:slab' +# pre pivot scripts are sourced just before we doing cleanup and switch over +# to the new root. +getarg 'rd.break=pre-udev' 'rdbreak=pre-udev' && emergency_shell -n pre-udev "Break before pre-udev" +source_hook pre-udev + +_modprobe_d=/etc/modprobe.d +if [ -d /usr/lib/modprobe.d ]; then + _modprobe_d=/usr/lib/modprobe.d +elif [ -d /lib/modprobe.d ]; then + _modprobe_d=/lib/modprobe.d +elif [ ! -d $_modprobe_d ]; then + mkdir -p $_modprobe_d +fi + +for i in $(getargs rd.driver.pre -d rdloaddriver=); do + ( + IFS=, + for p in $i; do + modprobe "$p" 2>&1 | vinfo + done + ) +done + +[ -d /etc/modprobe.d ] || mkdir -p /etc/modprobe.d + +for i in $(getargs rd.driver.blacklist -d rdblacklist=); do + ( + IFS=, + for p in $i; do + echo "blacklist $p" >> $_modprobe_d/initramfsblacklist.conf + done + ) +done + +for p in $(getargs rd.driver.post -d rdinsmodpost=); do + echo "blacklist $p" >> $_modprobe_d/initramfsblacklist.conf + _do_insmodpost=1 +done + +[ -n "$_do_insmodpost" ] && initqueue --settled --unique --onetime insmodpost.sh +unset _do_insmodpost _modprobe_d +unset i + +export -p > /dracut-state.sh +exit 0 diff --git a/modules.d/98dracut-systemd/dracut-shutdown-onfailure.service b/modules.d/98dracut-systemd/dracut-shutdown-onfailure.service new file mode 100644 index 0000000..0570535 --- /dev/null +++ b/modules.d/98dracut-systemd/dracut-shutdown-onfailure.service @@ -0,0 +1,11 @@ +# This file is part of dracut. + +[Unit] +Description=Service executing upon dracut-shutdown failure to perform cleanup +Documentation=man:dracut-shutdown.service(8) +DefaultDependencies=no + +[Service] +Type=oneshot +ExecStart=-/bin/rm /run/initramfs/shutdown +StandardError=null diff --git a/modules.d/98dracut-systemd/dracut-shutdown.service b/modules.d/98dracut-systemd/dracut-shutdown.service new file mode 100644 index 0000000..b2b704a --- /dev/null +++ b/modules.d/98dracut-systemd/dracut-shutdown.service @@ -0,0 +1,15 @@ +# This file is part of dracut. + +[Unit] +Description=Restore /run/initramfs on shutdown +Documentation=man:dracut-shutdown.service(8) +After=local-fs.target boot.mount boot.automount +Wants=local-fs.target +ConditionPathExists=!/run/initramfs/bin/sh +OnFailure=dracut-shutdown-onfailure.service + +[Service] +RemainAfterExit=yes +Type=oneshot +ExecStart=/bin/true +ExecStop=/usr/lib/dracut/dracut-initramfs-restore diff --git a/modules.d/98dracut-systemd/dracut-shutdown.service.8.asc b/modules.d/98dracut-systemd/dracut-shutdown.service.8.asc new file mode 100644 index 0000000..21ec88c --- /dev/null +++ b/modules.d/98dracut-systemd/dracut-shutdown.service.8.asc @@ -0,0 +1,53 @@ +DRACUT-SHUTDOWN.SERVICE(8) +=========================== +:doctype: manpage +:man source: dracut +:man manual: dracut + +NAME +---- +dracut-shutdown.service - unpack the initramfs to /run/initramfs + +SYNOPSIS +-------- +dracut-shutdown.service + +DESCRIPTION +----------- +This service unpacks the initramfs image to /run/initramfs. +systemd pivots into /run/initramfs at shutdown, so the root filesystem +can be safely unmounted. + +The following steps are executed during a shutdown: + +* systemd switches to the shutdown.target +* systemd starts /lib/systemd/system/shutdown.target.wants/dracut-shutdown.service +* dracut-shutdown.service executes /usr/lib/dracut/dracut-initramfs-restore which unpacks the initramfs to /run/initramfs +* systemd finishes shutdown.target +* systemd kills all processes +* systemd tries to unmount everything and mounts the remaining read-only +* systemd checks, if there is a /run/initramfs/shutdown executable +* if yes, it does a pivot_root to /run/initramfs and executes ./shutdown. The old root is then mounted on /oldroot. /usr/lib/dracut/modules.d/99shutdown/shutdown.sh is the shutdown executable. +* shutdown will try to umount every /oldroot mount and calls the various shutdown hooks from the dracut modules + +This ensures, that all devices are disassembled and unmounted cleanly. + +To debug the shutdown process, you can get a shell in the shutdown procedure +by injecting "rd.break=pre-shutdown rd.shell" or "rd.break=shutdown rd.shell". +---- +# mkdir -p /run/initramfs/etc/cmdline.d +# echo "rd.break=pre-shutdown rd.shell" > /run/initramfs/etc/cmdline.d/debug.conf +# touch /run/initramfs/.need_shutdown +---- + +In case the unpack of the initramfs fails, dracut-shutdown-onfailure.service +executes to make sure switch root doesn't happen, since it would result in +switching to an incomplete initramfs. + +AUTHORS +------- +Harald Hoyer + +SEE ALSO +-------- +*dracut*(8) diff --git a/modules.d/98dracut-systemd/dracut-tmpfiles.conf b/modules.d/98dracut-systemd/dracut-tmpfiles.conf new file mode 100644 index 0000000..3c21ce8 --- /dev/null +++ b/modules.d/98dracut-systemd/dracut-tmpfiles.conf @@ -0,0 +1,3 @@ +d /run/initramfs 0755 root root - +d /run/initramfs/log 0755 root root - +L /var/log - - - - ../run/initramfs/log diff --git a/modules.d/98dracut-systemd/emergency.service b/modules.d/98dracut-systemd/emergency.service new file mode 100644 index 0000000..27c69e1 --- /dev/null +++ b/modules.d/98dracut-systemd/emergency.service @@ -0,0 +1,29 @@ +# This file is part of dracut. + +[Unit] +Description=Emergency Shell +Documentation=man:dracut.bootup(7) +DefaultDependencies=no +After=systemd-vconsole-setup.service +Wants=systemd-vconsole-setup.service +Conflicts=shutdown.target +Before=shutdown.target + +[Service] +Environment=HOME=/ +Environment=DRACUT_SYSTEMD=1 +Environment=NEWROOT=/sysroot +WorkingDirectory=/ +ExecStart=/bin/dracut-emergency +ExecStopPost=-/usr/bin/systemctl --fail --no-block default +Type=idle +StandardInput=tty-force +StandardOutput=inherit +StandardError=inherit +KillMode=process +IgnoreSIGPIPE=no +TasksMax=infinity + +# Bash ignores SIGTERM, so we send SIGHUP instead, to ensure that bash +# terminates cleanly. +KillSignal=SIGHUP diff --git a/modules.d/98dracut-systemd/module-setup.sh b/modules.d/98dracut-systemd/module-setup.sh new file mode 100755 index 0000000..3195377 --- /dev/null +++ b/modules.d/98dracut-systemd/module-setup.sh @@ -0,0 +1,58 @@ +#!/bin/bash + +# called by dracut +check() { + [[ $mount_needs ]] && return 1 + + return 0 +} + +# called by dracut +depends() { + echo "systemd-initrd" + return 0 +} + +installkernel() { + return 0 +} + +# called by dracut +install() { + inst_script "$moddir/dracut-emergency.sh" /bin/dracut-emergency + inst_simple "$moddir/emergency.service" "${systemdsystemunitdir}"/emergency.service + inst_simple "$moddir/dracut-emergency.service" "${systemdsystemunitdir}"/dracut-emergency.service + inst_simple "$moddir/emergency.service" "${systemdsystemunitdir}"/rescue.service + + ln_r "${systemdsystemunitdir}/initrd.target" "${systemdsystemunitdir}/default.target" + + inst_script "$moddir/dracut-cmdline.sh" /bin/dracut-cmdline + inst_script "$moddir/dracut-cmdline-ask.sh" /bin/dracut-cmdline-ask + inst_script "$moddir/dracut-pre-udev.sh" /bin/dracut-pre-udev + inst_script "$moddir/dracut-pre-trigger.sh" /bin/dracut-pre-trigger + inst_script "$moddir/dracut-initqueue.sh" /bin/dracut-initqueue + inst_script "$moddir/dracut-pre-mount.sh" /bin/dracut-pre-mount + inst_script "$moddir/dracut-mount.sh" /bin/dracut-mount + inst_script "$moddir/dracut-pre-pivot.sh" /bin/dracut-pre-pivot + + inst_script "$moddir/rootfs-generator.sh" "$systemdutildir"/system-generators/dracut-rootfs-generator + + inst_hook cmdline 00 "$moddir/parse-root.sh" + + for i in \ + dracut-cmdline.service \ + dracut-cmdline-ask.service \ + dracut-initqueue.service \ + dracut-mount.service \ + dracut-pre-mount.service \ + dracut-pre-pivot.service \ + dracut-pre-trigger.service \ + dracut-pre-udev.service; do + inst_simple "$moddir/${i}" "$systemdsystemunitdir/${i}" + $SYSTEMCTL -q --root "$initdir" add-wants initrd.target "$i" + done + + inst_simple "$moddir/dracut-tmpfiles.conf" "$tmpfilesdir/dracut-tmpfiles.conf" + + inst_multiple sulogin +} diff --git a/modules.d/98dracut-systemd/parse-root.sh b/modules.d/98dracut-systemd/parse-root.sh new file mode 100755 index 0000000..90f145a --- /dev/null +++ b/modules.d/98dracut-systemd/parse-root.sh @@ -0,0 +1,38 @@ +#!/bin/sh + +type getarg > /dev/null 2>&1 || . /lib/dracut-lib.sh + +root=$(getarg root=) +case "${root#block:}" in + LABEL=* | UUID=* | PARTUUID=* | PARTLABEL=*) + root="block:$(label_uuid_to_dev "$root")" + rootok=1 + ;; + /dev/nfs | /dev/root) # ignore legacy + ;; + /dev/*) + root="block:${root}" + rootok=1 + ;; +esac + +if [ "$rootok" = "1" ]; then + root_dev="${root#block:}" + root_name="$(str_replace "$root_dev" '/' '\x2f')" + if ! [ -e "$hookdir/initqueue/finished/devexists-${root_name}.sh" ]; then + + # If a LUKS device needs unlocking via systemd in the initrd, assume + # it's for the root device. In that case, don't block on it if it's + # after remote-fs-pre.target since the initqueue is ordered before it so + # it will never actually show up (think Tang-pinned rootfs). + cat > "$hookdir/initqueue/finished/devexists-${root_name}.sh" << EOF +if ! grep -q After=remote-fs-pre.target /run/systemd/generator/systemd-cryptsetup@*.service 2>/dev/null; then + [ -e "$root_dev" ] +fi +EOF + { + printf '[ -e "%s" ] || ' "$root_dev" + printf 'warn "\"%s\" does not exist"\n' "$root_dev" + } >> "$hookdir/emergency/80-${root_name}.sh" + fi +fi diff --git a/modules.d/98dracut-systemd/rootfs-generator.sh b/modules.d/98dracut-systemd/rootfs-generator.sh new file mode 100755 index 0000000..cef3f49 --- /dev/null +++ b/modules.d/98dracut-systemd/rootfs-generator.sh @@ -0,0 +1,95 @@ +#!/bin/sh + +type getarg > /dev/null 2>&1 || . /lib/dracut-lib.sh + +generator_wait_for_dev() { + local _name + local _timeout + + _name=$(dev_unit_name "$1") + _timeout=$(getarg rd.timeout) + _timeout=${_timeout:-0} + + if ! [ -L "$GENERATOR_DIR"/initrd.target.wants/"${_name}".device ]; then + [ -d "$GENERATOR_DIR"/initrd.target.wants ] || mkdir -p "$GENERATOR_DIR"/initrd.target.wants + ln -s ../"${_name}".device "$GENERATOR_DIR"/initrd.target.wants/"${_name}".device + fi + + if ! [ -f "$GENERATOR_DIR"/"${_name}".device.d/timeout.conf ]; then + mkdir -p "$GENERATOR_DIR"/"${_name}".device.d + { + echo "[Unit]" + echo "JobTimeoutSec=$_timeout" + echo "JobRunningTimeoutSec=$_timeout" + } > "$GENERATOR_DIR"/"${_name}".device.d/timeout.conf + fi +} + +generator_mount_rootfs() { + local _type="$2" + local _flags="$3" + local _name + + [ -z "$1" ] && return 0 + + _name=$(dev_unit_name "$1") + if ! [ -f "$GENERATOR_DIR"/sysroot.mount ]; then + { + echo "[Unit]" + echo "Before=initrd-root-fs.target" + echo "Requires=systemd-fsck@${_name}.service" + echo "After=systemd-fsck@${_name}.service" + echo "[Mount]" + echo "Where=/sysroot" + echo "What=$1" + echo "Options=${_flags}" + echo "Type=${_type}" + } > "$GENERATOR_DIR"/sysroot.mount + fi + if ! [ -L "$GENERATOR_DIR"/initrd-root-fs.target.requires/sysroot.mount ]; then + [ -d "$GENERATOR_DIR"/initrd-root-fs.target.requires ] || mkdir -p "$GENERATOR_DIR"/initrd-root-fs.target.requires + ln -s ../sysroot.mount "$GENERATOR_DIR"/initrd-root-fs.target.requires/sysroot.mount + fi +} + +generator_fsck_after_pre_mount() { + local _name + + [ -z "$1" ] && return 0 + + _name=$(dev_unit_name "$1") + [ -d "$GENERATOR_DIR"/systemd-fsck@"${_name}".service.d ] || mkdir -p "$GENERATOR_DIR"/systemd-fsck@"${_name}".service.d + if ! [ -f "$GENERATOR_DIR"/systemd-fsck@"${_name}".service.d/after-pre-mount.conf ]; then + { + echo "[Unit]" + echo "After=dracut-pre-mount.service" + } > "$GENERATOR_DIR"/systemd-fsck@"${_name}".service.d/after-pre-mount.conf + fi + +} + +root=$(getarg root=) +case "${root#block:}" in + LABEL=* | UUID=* | PARTUUID=* | PARTLABEL=*) + root="block:$(label_uuid_to_dev "$root")" + rootok=1 + ;; + /dev/nfs) # ignore legacy /dev/nfs + ;; + /dev/*) + root="block:${root}" + rootok=1 + ;; +esac + +if [ "$rootok" = "1" ]; then + GENERATOR_DIR="$1" + [ -z "$GENERATOR_DIR" ] && exit 1 + [ -d "$GENERATOR_DIR" ] || mkdir -p "$GENERATOR_DIR" + + generator_wait_for_dev "${root#block:}" + generator_fsck_after_pre_mount "${root#block:}" + strstr "$(cat /proc/cmdline)" 'root=' || generator_mount_rootfs "${root#block:}" "$(getarg rootfstype=)" "$(getarg rootflags=)" +fi + +exit 0 |