diff options
author | Sam Thursfield <sam.thursfield@codethink.co.uk> | 2017-05-24 16:37:56 +0100 |
---|---|---|
committer | Sam Thursfield <sam.thursfield@codethink.co.uk> | 2017-05-24 16:37:56 +0100 |
commit | 0dfefccee468b4a7cbd32133e7d870c0524c79a9 (patch) | |
tree | 61e94da81350bee2ea85e9ca3c585eab3fbc8999 | |
parent | 646a18b3f362dc8f92aac31021f4a96fb41c87ed (diff) | |
parent | e5c71f0ca075bd29ffd55ec0c25804585bc21046 (diff) | |
download | definitions-0dfefccee468b4a7cbd32133e7d870c0524c79a9.tar.gz |
Add 'files/initramfs/' from commit 'e5c71f0ca075bd29ffd55ec0c25804585bc21046'
git-subtree-dir: files/initramfs
git-subtree-mainline: 646a18b3f362dc8f92aac31021f4a96fb41c87ed
git-subtree-split: e5c71f0ca075bd29ffd55ec0c25804585bc21046
-rw-r--r-- | files/initramfs/Makefile | 9 | ||||
-rwxr-xr-x | files/initramfs/configure | 1 | ||||
-rw-r--r-- | files/initramfs/init | 125 | ||||
-rw-r--r-- | files/initramfs/shutdown | 66 |
4 files changed, 201 insertions, 0 deletions
diff --git a/files/initramfs/Makefile b/files/initramfs/Makefile new file mode 100644 index 00000000..97ad4751 --- /dev/null +++ b/files/initramfs/Makefile @@ -0,0 +1,9 @@ + +SCRIPTS = init shutdown + +all: + +install: $(SCRIPTS) + for script in $^ ; do\ + install -D -m 755 "$$script" $(DESTDIR)/"$$script"; \ + done diff --git a/files/initramfs/configure b/files/initramfs/configure new file mode 100755 index 00000000..1a248525 --- /dev/null +++ b/files/initramfs/configure @@ -0,0 +1 @@ +#!/bin/sh diff --git a/files/initramfs/init b/files/initramfs/init new file mode 100644 index 00000000..65bf6e87 --- /dev/null +++ b/files/initramfs/init @@ -0,0 +1,125 @@ +#!/bin/sh +trap 'exec /bin/sh' INT EXIT + +# We need proc for reading the kernel command line +mount -n -t proc none /proc + +set -- $(cat /proc/cmdline) + +# We don't want to leave mount points around +umount /proc + +rootwait=true # defaults to off in the kernel, I think it's more useful on +for arg; do + case "$arg" in + root=LABEL=*) + if [ x"$root_type" != x ]; then + echo "Warning, multiple root= specified, using latest." + fi + root_type=label + root="${arg#root=LABEL=}" + ;; + root=UUID=*) + if [ x"$root_type" != x ]; then + echo "Warning, multiple root= specified, using latest." + fi + root_type=uuid + root="${arg#root=UUID=}" + ;; + root=*) + if [ x"$root_type" != x ]; then + echo "Warning, multiple root= specified, using latest." + fi + root_type=disk + root="${arg#root=}" + ;; + rootflags=*) + if [ x"$rootflags" != x ]; then + echo "Warning, multiple rootflags= specified, using latest." + fi + rootflags=",${arg#rootflags=}" + ;; + rootfstype=*) + if [ x"$rootflags" != x ]; then + echo "Warning, multiple rootfstype= specified, using latest." + fi + rootfstype="${arg#rootfstype=}" + ;; + rootdelay=*) + if [ x"$rootflags" != x ]; then + echo "Warning, multiple rootdelay= specified, using latest." + fi + rootfstype="${arg#rootdelay=}" + ;; + rootwait) + rootwait=true + ;; + norootwait) + rootwait=false + ;; + ro) + ro=ro + ;; + rw) + ro=rw + ;; + init=*) + init="${arg#init=}" + ;; + esac +done + +if [ x"$rootdelay" != x ]; then + sleep "$rootdelay" +fi + +if [ x"$rootfstype" = x ]; then + # Warn that busybox may not be able to auto-detect rootfs type + cat <<\EOF +Warning, rootfs type not specified, auto-detection of type is slow and +may fail. Please add rootfstype=$type to kernel command line. +EOF +fi + +mount -n -t devtmpfs devtmpfs /dev +while true; do + case "$root_type" in + disk) + if mount -n -t "${rootfstype}" -o "${ro-rw}""$rootflags" "$root" /mnt; then + break + else + echo disk $root not found + blkid + fi + ;; + label) + disk="$(findfs LABEL="$root")" + if [ x"$disk" = x ]; then + echo disk with label $root not found + blkid + else + mount -n -t "${rootfstype}" -o "${ro-rw}""$rootflags" "$disk" /mnt && break + fi + ;; + uuid) + disk="$(findfs UUID="$root")" + if [ x"$disk" = x ]; then + echo disk with UUID $root not found + blkid + else + mount -n -t "${rootfstype}" -o "${ro-rw}""$rootflags" "$disk" /mnt && break + fi + ;; + '') + echo "Error, no root specified" + exit 1 + ;; + esac + if "$rootwait"; then + echo Trying again in 0.5 seconds + sleep 0.5 + fi +done +umount -n /dev + +exec switch_root -c /dev/console /mnt "${init-/sbin/init}" diff --git a/files/initramfs/shutdown b/files/initramfs/shutdown new file mode 100644 index 00000000..09281dd3 --- /dev/null +++ b/files/initramfs/shutdown @@ -0,0 +1,66 @@ +#!/bin/sh + +fail(){ + echo "$@" >&2 + # The behaviour on failure of systemd when shutting down without a + # shutdownramfs is to freeze if it fails, but the behaviour of an initramfs + # on failure is to drop you into a recovery shell. The latter seems more + # useful. + exec /bin/sh +} + +startswith(){ + # Filter out lines that don't start with $1 + # grep ^EXPR is usually sufficient, but would require escaping of EXPR. + # Instead this compares the line to the line with its prefix stripped, + # so if the line is different, then it started with that prefix. + # It's ugly, but is less logic than escaping the regular expression and + # using grep, more reliable than not making any effort to escape, and + # less surprising than requiring the parameter to be pre-escaped. + while read -r line; do + if [ "${line#"$1"}" != "$line" ]; then + printf '%s\n' "$line" + fi + done +} + +recursive_umount(){ + # Recursively unmount every mountpoint under $1. + # This works by filtering to select mountpoints from mountinfo that start + # with the absolute path of the directory given. + # It unmounts in reverse-order, so that it may unmount dependent mounts + # first, and it has to handle the paths having octal escape sequences. + set -- "$(readlink -f "$1")" + cut -d' ' -f5 /proc/self/mountinfo | startswith "$1" \ + | sort -r | while read -r mp; do + umount "$(echo -e "$mp")" + done +} + +# Give the rootfs another chance to write its state to disk. +sync + +# Kill any http://www.freedesktop.org/wiki/Software/systemd/RootStorageDaemons/ +# as we don't have any facility to cleanly shut them down in this initramfs. +killall5 + +# Recursively unmount the old root, so they have a chance of performing +# unmount-time cleanup. +recursive_umount /oldroot + +case "$1" in +reboot|poweroff|halt) + if ! "$1" -f; then + fail "$1 command failed" + fi + ;; +kexec) + # probably don't have this, but we'll try anyway + if ! kexec -e; then + fail "$1 command failed" + fi + ;; +*) + fail "Unrecognized shutdown verb $1" + ;; +esac |