diff --git a/README.md b/README.md index e8fd697..8f3c96b 100644 --- a/README.md +++ b/README.md @@ -2,10 +2,6 @@ Restart init. ```text -WARNING: This utility has not been thoroughly tested. It could freeze the machine or panic the kernel. - Maybe it won't, but anyway, make sure you have viewed each line of its code and that you fully understand them. - - Usage: reinit [-i ] [-r [-o ]] [options] [-- init_options] @@ -15,11 +11,13 @@ Options: -i, --newinit the file to execute as the new init; default: current init -r, --newroot the mountpoint to use as new root; default: / -o, --putold the path to mount the old root if --newroot is set; default: /._tmp_reinit/putold + -b, --bbinit use busybox as the new init; you'll need to spicify an applet in init_options - -b, --bbinit use busybox as the new init - -k, --nokill do not kill old processes; PIDs of old processes will be stored in environment variable $oldproc - -s, --nostop do not stop old processes (implies --nokill); may make the kernel panic when used with -r - -f, --keepfd do not close fds for the new init + -k, --nokill do not kill old processes; PIDs of old processes will be stored in environment variable $oldproc + -s, --nostop do not stop old processes (implies --nokill); may make the kernel panic when used with -r + -f, --keepfd do not close fds for the new init + -u, --umount umount /proc, /dev, /sys, /run, /tmp (default when newroot == / && !nostop) + --no-umount do not umount /proc, /dev, /sys, /run, /tmp (default) -h, --help display this help -V, --version display version diff --git a/reinit b/reinit index 5d1adf0..7aa4738 100755 --- a/reinit +++ b/reinit @@ -6,10 +6,11 @@ export LC_ALL=C # Exit on error. set -e -echo "WARNING: This utility has not been thoroughly tested. It could freeze the machine or panic the kernel." -echo " Maybe it won't, but anyway, make sure you have viewed each line of its code and that you fully understand them." -echo "INFO: Press return / enter to continue: " -read +# echo "WARNING: This utility has not been thoroughly tested. It could freeze the machine or panic the kernel." +# echo " Maybe it won't, but anyway, make sure you have viewed each line of its code and that you fully understand them." +# echo +#echo "INFO: Press return / enter to continue: " +#read # echo " Edit the source code and remove the next exit statement." # exit -1 @@ -17,12 +18,13 @@ read newinit= newroot=/ putold=/._tmp_reinit/oldroot +umount=d for i in nokill nostop keepfd; do eval $i=0 done # Parse options. -options="$(getopt -o i:r:o:b::k::s::f::h::V:: -l newinit -l newroot -l putold -l bbinit -l nokill -l nostop -l keepfd -l help -l version -s bash -n reinit -- "$@")" || (echo "Try 'reinit --help' for more information." && exit 22) +options="$(getopt -o i:r:o:b::k::s::f::u::h::V:: -l newinit -l newroot -l putold -l bbinit -l nokill -l nostop -l keepfd -l umount -l no-umount -l help -l version -s bash -n reinit -- "$@")" || (echo "Try 'reinit --help' for more information." && exit 22) eval set -- "$options" while true; do @@ -39,11 +41,11 @@ while true; do putold="$2" shift 2 ;; - -b|--bbinit) newinit='/._tmp_reinit/busybox' shift 2 ;; + -k|--nokill) nokill=1 shift 2 @@ -56,6 +58,14 @@ while true; do keepfd=1 shift 2 ;; + -u|--umount) + umount=1 + shift 2 + ;; + --no-umount) + umount=0 + shift 2 + ;; -h|--help) cat << END @@ -69,11 +79,13 @@ Options: -i, --newinit the file to execute as the new init; default: current init -r, --newroot the mountpoint to use as new root; default: / -o, --putold the path to mount the old root if --newroot is set; default: /._tmp_reinit/putold + -b, --bbinit use busybox as the new init; you'll need to spicify an applet in init_options - -b, --bbinit use busybox as the new init - -k, --nokill do not kill old processes; PIDs of old processes will be stored in environment variable \$oldproc - -s, --nostop do not stop old processes (implies --nokill); may make the kernel panic when used with -r - -f, --keepfd do not close fds for the new init + -k, --nokill do not kill old processes; PIDs of old processes will be stored in environment variable \$oldproc + -s, --nostop do not stop old processes (implies --nokill); may make the kernel panic when used with -r + -f, --keepfd do not close fds for the new init + -u, --umount umount /proc, /dev, /sys, /run, /tmp (default when newroot == / && !nostop) + --no-umount do not umount /proc, /dev, /sys, /run, /tmp (default) -h, --help display this help -V, --version display version @@ -82,7 +94,7 @@ END shift 2 ;; -V|--version) - echo 'reinit 0.0.0' + echo 'reinit 1.0.0' exit 0 shift 2 ;; @@ -104,13 +116,14 @@ done # Environment checks +busybox_path="$(realpath "$(dirname -- "$0")"/busybox)" + qwhich() { which -- "$@" >/dev/null 2>/dev/null /dev/null 2>/dev/null /dev/null 2>/dev/null /._tmp_reinit/current_init cat >._tmp_reinit/init << END #!$newroot/._tmp_reinit/busybox ash +# From now on we'll use sync frequently to avoid losing unsynced data if we panic. +sync + # Do not exit on any errors or signals. set +e trap '' \$(kill -l | sed 's/\s/\\n/g' | grep '[a-zA-Z]') @@ -235,10 +284,12 @@ current_init="\$(cat /._tmp_reinit/current_init)" nokill=$nokill nostop=$nostop keepfd=$keepfd +umount=$umount failed=0 cd "\$newroot" +sync # Mount dev and proc if they are not mounted if ! mountpoint -q dev; then @@ -252,53 +303,66 @@ fi # The shell running on tty1 is still the script's session leader, so killing it would cause the script to exit. proc="" - freeze() { - for c2 in 0 1 2; do # Try three times with 100ms interval. - for c1 in 0 1 2; do # For each try, scan three times continuously. - - proc="" - - for i in \$(ls -1 /proc | grep -E '^[0-9]+\$' | grep -v '^1\$'); do - if readlink proc/\$i/exe >/dev/null 2>/dev/null /dev/null 2>/dev/null ._tmp_reinit/prepare_env << END +sync + set +e trap '' \$(kill -l | sed 's/\s/\\n/g' | grep '[a-zA-Z]') cd / # Now it's safe to kill all old processes. -if [ \$nokill == 0 -a ! -z "\$proc" ]; then - kill -9 \$proc >/dev/null 2>/dev/null /dev/null 2>/dev/null /dev/null 2>/dev/null /dev/null 2>/dev/null /dev/null 2>/dev/null /dev/null 2>/dev/null /dev/null 2>/dev/null /dev/null 2>/dev/null /dev/null 2>/dev/null