1) prepare common emergency_shell

emergency_shell functions from 99base/init and 99shutdown/shutdown were
very similar, which forced to do similar changes in both places

The core functionality was moved to 99base/dracut-lib.sh as
emergency_shell_core(), which is now called through wrapping
emergency_shell(), with two simple internal knobs (type and error
message). wait_for_loginit() was moved to the lib as well.

2) shell job control fixups

Terminal (the one provided to command line) is thoroughly checked if it
really is terminal. In case of any problems we fallback to /dev/tty1
(if --ctty was used) or if it doesn't exist for whatever reason (or no
--ctty was used), to /dev/console. Additionally, shell is never spawned
through setsid on /dev/console (little point to do so).

This should cover all possible corner cases.
---
 modules.d/99base/dracut-lib.sh |   98 ++++++++++++++++++++++++++++++++++++++++
 modules.d/99base/init          |   64 --------------------------
 modules.d/99shutdown/shutdown  |   37 ++-------------
 3 files changed, 102 insertions(+), 97 deletions(-)

diff --git a/modules.d/99base/dracut-lib.sh b/modules.d/99base/dracut-lib.sh
index cf5aae6..ff80eda 100755
--- a/modules.d/99base/dracut-lib.sh
+++ b/modules.d/99base/dracut-lib.sh
@@ -555,3 +555,101 @@ usable_root() {
     [ -e "$1/lib" -o -e "$1/lib64" ] || return 1
     return 0
 }
+
+wait_for_loginit()
+{
+    set +x
+    [ "$RD_DEBUG" = "yes" ] || return
+    [ -e /run/initramfs/loginit.pipe ] || return
+    echo "DRACUT_LOG_END"
+    exec 0<>/dev/console 1<>/dev/console 2<>/dev/console
+    # wait for loginit
+    i=0
+    while [ $i -lt 10 ]; do
+        if [ ! -e /run/initramfs/loginit.pipe ]; then
+            j=$(jobs)
+            [ -z "$j" ] && break
+            [ -z "${j##*Running*}" ] || break
+        fi
+        sleep 0.1
+        i=$(($i+1))
+    done
+
+    if [ $i -eq 10 ]; then
+        kill %1 >/dev/null 2>&1
+        kill $(while read line;do echo $line;done</run/initramfs/loginit.pid)
+    fi
+
+    set -x
+    rm -f /run/initramfs/loginit.pipe /run/initramfs/loginit.pid
+}
+
+# meant only to be called through emergency_shell wrapper function;
+# standard version is defined below, shutdown override is in
+# 99shutdown/shutdown
+#
+# $1     - 's' or 'i', depending if it was called from shutdown or init
+# $2     - error message
+# $3     - "name", or:
+# $3, $4 - "-n" "name"
+# remaining arguments - remaining message passed to wrapper
+#
+emergency_shell_core()
+{
+    local _type; local _mesg
+    set +e
+
+    _type="$1"; _mesg="$2"; shift 2
+    if [ "$1" = "-n" ]; then
+        _rdshell_name=$2
+        shift 2
+    else
+        _rdshell_name=dracut
+    fi
+    echo ; echo
+    warn "$*"
+    echo
+    if [ $_type = i ]; then
+        source_hook emergency
+        wait_for_loginit
+        [ -e /run/initramfs/.die ] && exit 1
+    else
+        source_hook shutdown-emergency
+    fi
+    if getargbool 1 rd.shell -y rdshell || getarg rd.break rdbreak; then
+        local _tty; local _tmp
+
+        _tty=/dev/console
+        if type setsid >/dev/null 2>&1; then
+            [ -c /dev/tty1 ] && _tty=/dev/tty1
+            _tmp="$(getarg rd.ctty=)" && _tmp="/dev/${_tmp##*/}"
+            if [ -c "$_tmp" ] && exec 9<>$_tmp >/dev/null 2>&1; then
+                [ -t 9 ] && _tty=$_tmp
+                exec 9>&-
+            fi
+        fi
+        [ -x /lib/udev/console_init ] && /lib/udev/console_init $_tty
+
+        echo "Dropping to debug shell."
+        echo
+        export PS1="$_rdshell_name:\${PWD}# "
+        [ -e /.profile ] || >/.profile
+        if [ $_tty != /dev/console ]; then
+            setsid sh -i -l 0<$_tty 1>$_tty 2>&1
+        else
+            sh -i -l 0<$_tty 1>$_tty 2>&1
+        fi
+    else
+        [ $_type = s ] && exec /lib/systemd/systemd-shutdown "$@"
+        warn "$_mesg"
+        # cause a kernel panic
+        exit 1
+    fi
+}
+
+emergency_shell()
+{
+    emergency_shell_core i \
+        "Boot has failed. To debug this issue add \"rd.shell\" to the kernel 
command line." \
+        "$@"
+}
diff --git a/modules.d/99base/init b/modules.d/99base/init
index 3da6abd..16ed3fc 100755
--- a/modules.d/99base/init
+++ b/modules.d/99base/init
@@ -10,70 +10,6 @@
 
 export -p > /tmp/export.orig
 
-wait_for_loginit()
-{
-    set +x
-    [ "$RD_DEBUG" = "yes" ] || return
-    [ -e /run/initramfs/loginit.pipe ] || return
-    echo "DRACUT_LOG_END"
-    exec 0<>/dev/console 1<>/dev/console 2<>/dev/console
-        # wait for loginit
-    i=0
-    while [ $i -lt 10 ]; do
-        if [ ! -e /run/initramfs/loginit.pipe ]; then
-            j=$(jobs)
-            [ -z "$j" ] && break
-            [ -z "${j##*Running*}" ] || break
-        fi
-        sleep 0.1
-        i=$(($i+1))
-    done
-
-    if [ $i -eq 10 ]; then
-        kill %1 >/dev/null 2>&1
-        kill $(while read line;do echo $line;done</run/initramfs/loginit.pid)
-    fi
-
-    set -x
-    rm -f /run/initramfs/loginit.pipe /run/initramfs/loginit.pid
-}
-
-emergency_shell()
-{
-    local _ctty
-    set +e
-    if [ "$1" = "-n" ]; then
-        _rdshell_name=$2
-        shift 2
-    else
-        _rdshell_name=dracut
-    fi
-    echo ; echo
-    warn $@
-    source_hook emergency
-    echo
-    wait_for_loginit
-    [ -e /run/initramfs/.die ] && exit 1
-    if getargbool 1 rd.shell -y rdshell || getarg rd.break rdbreak; then
-        echo "Dropping to debug shell."
-        echo
-        export PS1="$_rdshell_name:\${PWD}# "
-        [ -e /.profile ] || >/.profile
-        _ctty=/dev/console
-        if type setsid >/dev/null 2>&1; then
-            _ctty="$(getarg rd.ctty=)" && _ctty="/dev/${_ctty##*/}"
-            [ -c "$_ctty" ] || _ctty=/dev/tty1
-            setsid sh -i -l 0<$_ctty 1>$_ctty 2>&1
-        else
-            sh -i -l 0<$_ctty 1>$_ctty 2>&1
-        fi
-    else
-        warn "Boot 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
 OLDPATH=$PATH
 PATH=/usr/sbin:/usr/bin:/sbin:/bin
diff --git a/modules.d/99shutdown/shutdown b/modules.d/99shutdown/shutdown
index 21bb37f..8a44e8f 100755
--- a/modules.d/99shutdown/shutdown
+++ b/modules.d/99shutdown/shutdown
@@ -7,44 +7,15 @@
 # Copyright 2011, Red Hat, Inc.
 # Harald Hoyer <har...@redhat.com>
 
-#!/bin/sh
 . /lib/dracut-lib.sh
 export TERM=linux
 
+# override standard function
 emergency_shell()
 {
-    local _ctty
-    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 ] || >/.profile
-        _ctty=/dev/console
-        if type setsid >/dev/null 2>&1; then
-            _ctty="$(getarg rd.ctty=)" && _ctty="/dev/${_ctty##*/}"
-            [ -c "$_ctty" ] || _ctty=/dev/tty1
-            setsid sh -i -l 0<$_ctty 1>$_ctty 2>&1
-        else
-            sh -i -l 0<$_ctty 1>$_ctty 2>&1
-        fi
-    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
+    emergency_shell_core s \
+        "Shutdown has failed. To debug this issue add \"rd.shell\" to the 
kernel command line." \
+        "$@"
 }
 
 trap "emergency_shell Signal caught!" 0
-- 
1.7.5.3

--
To unsubscribe from this list: send the line "unsubscribe initramfs" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to