From 168fa7e5712e7cce91f130c5a15573b4e88697fb Mon Sep 17 00:00:00 2001 From: Harald Hoyer Date: Mon, 30 May 2011 17:27:36 +0200 Subject: [PATCH] base: add shutdown script to be called from systemd --- NEWS | 1 + dracut-functions | 2 +- dracut.conf.d/fedora.conf.example | 3 +- modules.d/99shutdown/module-setup.sh | 27 +++++++++ modules.d/99shutdown/shutdown | 87 ++++++++++++++++++++++++++++ 5 files changed, 118 insertions(+), 2 deletions(-) create mode 100755 modules.d/99shutdown/module-setup.sh create mode 100755 modules.d/99shutdown/shutdown diff --git a/NEWS b/NEWS index 47d5d2c0f..cb80df8bb 100644 --- a/NEWS +++ b/NEWS @@ -2,6 +2,7 @@ dracut-011 ========== - use udev-168 features for shutting down udev - introduce "--prefix" to put all initramfs files in /run/initramfs +- new shutdown script dracut-010 ========== diff --git a/dracut-functions b/dracut-functions index 4d5a78a90..e3e039222 100755 --- a/dracut-functions +++ b/dracut-functions @@ -461,7 +461,7 @@ inst() { [[ $hookdirs ]] || { hookdirs="cmdline pre-udev pre-trigger netroot initqueue pre-mount" - hookdirs+=" pre-pivot mount emergency" + hookdirs+=" pre-pivot mount emergency emergency-shutdown shutdown" export hookdirs } diff --git a/dracut.conf.d/fedora.conf.example b/dracut.conf.d/fedora.conf.example index 122f6575c..8ca67d4b0 100644 --- a/dracut.conf.d/fedora.conf.example +++ b/dracut.conf.d/fedora.conf.example @@ -2,5 +2,6 @@ # i18n i18n_vars="/etc/sysconfig/keyboard:KEYTABLE-KEYMAP /etc/sysconfig/i18n:SYSFONT-FONT,FONTACM-FONT_MAP,FONT_UNIMAP" -add_dracutmodules+=" rpmversion " +add_dracutmodules+=" rpmversion shutdown " stdloglvl=3 +prefix=/run/initramfs diff --git a/modules.d/99shutdown/module-setup.sh b/modules.d/99shutdown/module-setup.sh new file mode 100755 index 000000000..c4d2bb535 --- /dev/null +++ b/modules.d/99shutdown/module-setup.sh @@ -0,0 +1,27 @@ +#!/bin/bash +# -*- mode: shell-script; indent-tabs-mode: nil; sh-basic-offset: 4; -*- +# ex: ts=8 sw=4 sts=4 et filetype=sh + +check() { + return 255 +} + +depends() { + echo base + return 0 +} + +install() { + local _d + dracut_install umount + dracut_install poweroff reboot halt + dracut_install -o kexec + inst "$moddir/shutdown" "$prefix/shutdown" + [ -e "${initdir}/lib" ] || mkdir -m 0755 -p ${initdir}/lib + mkdir -m 0755 -p ${initdir}/lib/dracut + mkdir -m 0755 -p ${initdir}/lib/dracut/hooks + for _d in $hookdirs shutdown shutdown-emergency; do + mkdir -m 0755 -p ${initdir}/lib/dracut/hooks/$_d + done +} + diff --git a/modules.d/99shutdown/shutdown b/modules.d/99shutdown/shutdown new file mode 100755 index 000000000..bff29b9ef --- /dev/null +++ b/modules.d/99shutdown/shutdown @@ -0,0 +1,87 @@ +#!/bin/sh +# -*- mode: shell-script; indent-tabs-mode: nil; sh-basic-offset: 4; -*- +# ex: ts=8 sw=4 sts=4 et filetype=sh +# +# Licensed under the GPLv2 +# +# Copyright 2011, Red Hat, Inc. +# Harald Hoyer + +#!/bin/sh +. /lib/dracut-lib.sh +export TERM=linux + +emergency_shell() +{ + set +e + if [ "$1" = "-n" ]; then + _rdshell_name=$2 + shift 2 + else + _rdshell_name=dracut + fi + echo ; echo + warn $@ + source_hook shutdown-emergency + echo + if getargbool 1 rd.shell -y rdshell || getarg rd.break rdbreak; then + [ -x /lib/udev/console_init ] && /lib/udev/console_init /dev/console + echo "Dropping to debug shell." + echo + export PS1="$_rdshell_name:\${PWD}# " + [ -e /.profile ] || echo "exec 0<>/dev/console 1<>/dev/console 2<>/dev/console" > /.profile + sh -i -l + else + exec /lib/systemd/systemd-shutdown "$@" + warn "Shutdown has failed. To debug this issue add \"rdshell\" to the kernel command line." + # cause a kernel panic + exit 1 + fi +} + +trap "emergency_shell Signal caught!" 0 + +getarg 'rd.break=pre-shutdown' && emergency_shell -n cmdline "Break before pre-shutdown" + +umount_a() { + local _did_umount="n" + while read a mp a; do + if strstr "$mp" oldroot; then + if umount "$mp"; then + _did_umount="y" + echo "Unmounted $mp." + fi + fi + done /dev/null || break + _cnt=$(($_cnt+1)) +done +[ $_cnt -ge 40 ] && umount_a + +check_finished() { + local f + for f in $hookdir/shutdown/*.sh; do + [ -e "$f" ] || continue + ( . "$f" ) || return 1 + done + return 0 +} + +_cnt=0 +while [ $_cnt -le 40 ]; do + check_finished 2>/dev/null && break + _cnt=$(($_cnt+1)) +done +[ $_cnt -ge 40 ] && check_finished + +getarg 'rd.break=shutdown' && emergency_shell -n cmdline "Break before shutdown" +[ "$1" = "reboot" ] && reboot -f -d -n --no-wall +[ "$1" = "poweroff" ] && poweroff -f -d -n --no-wall +[ "$1" = "halt" ] && halt -f -d -n --no-wall +[ "$1" = "kexec" ] && kexec -e -- 2.47.3