[arch-projects] [mkinitcpio][PATCH 00/11] init cleanup and fsck impl
Hey all, I've been working on implementing fsck support for mkinitcpio, and I'm at the point where I think I need some feedback. There's a lot of cleanup that leads up to the fsck, and you're welcome to disagree with any of that as well, but what I'm looking at the moment is a few questions regarding the actual fsck work: 1) How much do we want to try to repair automatically? Currently I'm passing similar flags to what we pass in the initscripts, but maybe there's a reason to do things differently here. 2) What return codes should we be bailing to a rescue shell on and forcing user intervention? Give it a whirl. I've probably broken something, but my VMs seem happy with it so far. d Dave Reisner (11): Makefile: install binaries to /usr/bin install/ide: remove install hook init: don't tell the kernel about the path to modprobe init: create /run/initramfs after mounting /run init_functions: refactor poll_device autodetect: store rootfstype for use by other hooks init: use util-linux's /bin/mount init_functions: move root resolution to separate function init_functions: generalize resolve_device fsck: implement basic fsck support install/fsck: new install hook to add fsck and helpers Makefile | 9 ++-- init | 18 ++++++- init_functions | 142 +++++++++++++++++++++++++++++----------------------- install/autodetect | 2 +- install/base | 3 + install/fsck | 28 ++++++++++ install/ide | 17 ------ 7 files changed, 131 insertions(+), 88 deletions(-) create mode 100644 install/fsck delete mode 100644 install/ide -- 1.7.7.2
Signed-off-by: Dave Reisner <dreisner@archlinux.org> --- Makefile | 9 ++++----- 1 files changed, 4 insertions(+), 5 deletions(-) diff --git a/Makefile b/Makefile index 6ddf2cb..3e7966d 100644 --- a/Makefile +++ b/Makefile @@ -3,8 +3,7 @@ VERSION = $(shell if test -f VERSION; then cat VERSION; else git describe | sed 's/-/./g'; fi) DIRS = \ - /bin \ - /sbin \ + /usr/bin \ /etc/bash_completion.d \ /etc/mkinitcpio.d \ /lib/initcpio/hooks \ @@ -26,13 +25,13 @@ install: all -e 's|^INSTDIR=.*|INSTDIR=/lib/initcpio/install|' \ -e 's|^PRESETDIR=.*|PRESETDIR=/etc/mkinitcpio.d|' \ -e 's|%VERSION%|${VERSION}|g' \ - < mkinitcpio > ${DESTDIR}/sbin/mkinitcpio + < mkinitcpio > ${DESTDIR}/usr/bin/mkinitcpio sed -e 's|\(^declare FUNCTIONS\)=.*|\1=/lib/initcpio/functions|' \ -e 's|%VERSION%|${VERSION}|g' \ - < lsinitcpio > ${DESTDIR}/bin/lsinitcpio + < lsinitcpio > ${DESTDIR}/usr/bin/lsinitcpio - chmod 755 ${DESTDIR}/bin/lsinitcpio ${DESTDIR}/sbin/mkinitcpio + chmod 755 ${DESTDIR}/usr/bin/lsinitcpio ${DESTDIR}/usr/bin/mkinitcpio install -m644 mkinitcpio.conf ${DESTDIR}/etc/mkinitcpio.conf install -m755 -t ${DESTDIR}/lib/initcpio init -- 1.7.7.3
On Sat, Nov 12, 2011 at 1:55 PM, Dave Reisner <d@falconindy.com> wrote:
Signed-off-by: Dave Reisner <dreisner@archlinux.org>
Acked-by: Tom Gundersen <teg@jklm.no>
Arch no longer has support for the ancient IDE subsystem, and most other distros don't either. Signed-off-by: Dave Reisner <dreisner@archlinux.org> --- install/ide | 17 ----------------- 1 files changed, 0 insertions(+), 17 deletions(-) delete mode 100644 install/ide diff --git a/install/ide b/install/ide deleted file mode 100644 index a8d9e97..0000000 --- a/install/ide +++ /dev/null @@ -1,17 +0,0 @@ -#!/bin/bash - -build() { - MODULES="$(checked_modules "/ide/" | grep -v "legacy")" - - [[ $MODULES ]] && MODULES+=" ide-gd_mod?" -} - -help() { - cat <<HELPEOF -This hook loads the necessary modules for an ide root device, using the old ide -subsystem. Detection will take place at runtime. To minimize the modules in -the image, add the autodetect hook too. -HELPEOF -} - -# vim: set ft=sh ts=4 sw=4 et: -- 1.7.7.3
On Sat, Nov 12, 2011 at 1:55 PM, Dave Reisner <d@falconindy.com> wrote:
Arch no longer has support for the ancient IDE subsystem, and most other distros don't either.
Might this not be needed with an LTS kernel? In such a case there would probably be other issues as well (especially with udev), but it is worth considering. -t
On Sat, Nov 12, 2011 at 03:26:24PM +1100, Tom Gundersen wrote:
On Sat, Nov 12, 2011 at 1:55 PM, Dave Reisner <d@falconindy.com> wrote:
Arch no longer has support for the ancient IDE subsystem, and most other distros don't either.
Might this not be needed with an LTS kernel? In such a case there would probably be other issues as well (especially with udev), but it is worth considering.
-t
Yep, belaying this for now. d
Remove this ancient relic. It's not been needed in a very long time. Signed-off-by: Dave Reisner <dreisner@archlinux.org> --- init | 2 -- 1 files changed, 0 insertions(+), 2 deletions(-) diff --git a/init b/init index c185375..6787060 100644 --- a/init +++ b/init @@ -23,8 +23,6 @@ else fi mount -t tmpfs run /run -o nosuid,nodev,mode=755,size=10M -echo "/sbin/modprobe" > /proc/sys/kernel/modprobe - # parse the kernel command line parse_cmdline -- 1.7.7.3
On Sat, Nov 12, 2011 at 1:55 PM, Dave Reisner <d@falconindy.com> wrote:
Remove this ancient relic. It's not been needed in a very long time.
Signed-off-by: Dave Reisner <dreisner@archlinux.org>
This is not used by anything in the kernel any longer. It might be used by out-of-tree modules, but in that case the default value is /sbin/modprobe anyway. If someone uses this and changes the value at compile time, I guess they know what they are doing and we should not override it. Acked-by: Tom Gundersen <teg@jklm.no>
We'll use this as a channel to communicate with later userspace. Signed-off-by: Dave Reisner <dreisner@archlinux.org> --- init | 1 + 1 files changed, 1 insertions(+), 0 deletions(-) diff --git a/init b/init index 6787060..975368b 100644 --- a/init +++ b/init @@ -22,6 +22,7 @@ else mknod /dev/mem c 1 1 fi mount -t tmpfs run /run -o nosuid,nodev,mode=755,size=10M +mkdir /run/initramfs # parse the kernel command line parse_cmdline -- 1.7.7.3
On Sat, Nov 12, 2011 at 1:55 PM, Dave Reisner <d@falconindy.com> wrote:
We'll use this as a channel to communicate with later userspace.
Signed-off-by: Dave Reisner <dreisner@archlinux.org>
As mentioned on IRC: I agree with the idea, but maybe we could go one step further: Add /bin/cp from coreutils and rather than just creating /run/initramfs, copy the whole initramfs to /run/initramfs so we have access to the whole initramfs from the real system. This is a prerequisite of proper shutdownramfs, but I think it could also open the door for other interesting features, so we shouldn't necessarily link it to the shutdown stuff. -t
Beyond stylistic cleanup, add a conditional to ensure that we don't show the 'waiting for device' message if it already exists. Signed-off-by: Dave Reisner <dreisner@archlinux.org> --- init_functions | 23 ++++++++++++----------- 1 files changed, 12 insertions(+), 11 deletions(-) diff --git a/init_functions b/init_functions index e026929..7dd0968 100644 --- a/init_functions +++ b/init_functions @@ -8,20 +8,21 @@ err () { } poll_device() { - device="$1" - if [ "$2" -ge 0 ]; then - seconds="$2" - else - seconds=5 - fi - if [ "${udevd_running}" -eq 1 ]; then - msg "Waiting ${seconds} seconds for device ${device} ..." - while [ ! -b "${device}" -a ${seconds} -gt 0 ]; do + local device=$1 seconds=${2//[!0-9]} + + [ -z "$seconds" ] && seconds=5 + + [ -b "$device" ] && return 0 + + if [ "$udevd_running" -eq 1 ]; then + msg "Waiting $seconds seconds for device $device ..." + while [ ! -b "$device" -a "$seconds" -gt 0 ]; do sleep 1 - seconds=$((${seconds}-1)) + seconds=$(( $seconds - 1 )) done fi - [ -b "${device}" ] + + [ -b "$device" ] } launch_interactive_shell() { -- 1.7.7.3
Signed-off-by: Dave Reisner <dreisner@archlinux.org> --- install/autodetect | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diff --git a/install/autodetect b/install/autodetect index 35f1cb2..5537f7c 100644 --- a/install/autodetect +++ b/install/autodetect @@ -10,7 +10,7 @@ build() { auto_modules | grep -xEv '(ata|ide)_generic' >"$MODULE_FILE" - if ! findmnt -uno fstype "${BASEDIR:-/}" >>"$MODULE_FILE"; then + if ! rootfstype=$(findmnt -uno fstype "${BASEDIR:-/}" | tee -a "$MODULE_FILE"); then error "failed to detect root filesystem" fs_autodetect_failed=1 fi -- 1.7.7.3
On Fri, Nov 11, 2011 at 8:55 PM, Dave Reisner <d@falconindy.com> wrote:
Signed-off-by: Dave Reisner <dreisner@archlinux.org> --- install/autodetect | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/install/autodetect b/install/autodetect index 35f1cb2..5537f7c 100644 --- a/install/autodetect +++ b/install/autodetect @@ -10,7 +10,7 @@ build() {
auto_modules | grep -xEv '(ata|ide)_generic' >"$MODULE_FILE"
- if ! findmnt -uno fstype "${BASEDIR:-/}" >>"$MODULE_FILE"; then + if ! rootfstype=$(findmnt -uno fstype "${BASEDIR:-/}" | tee -a "$MODULE_FILE"); then error "failed to detect root filesystem" fs_autodetect_failed=1 fi -- 1.7.7.3
This patch along with associated changed to `init_functions` appears to be causing `rootfstype=xyz` on kernel boot to be ignored (since it's never checked) ... are we to use `fstype` in it's place? -- C Anthony
Providing this means we no longer need blkid for FS detection, as mount will do this for us. Adds a slight bloat to the image, in exchange for a huge convenience. Messaging is changed to assume that /bin/mount will provide useful feedback for us on failure. Signed-off-by: Dave Reisner <dreisner@archlinux.org> --- init_functions | 15 ++------------- install/base | 3 +++ 2 files changed, 5 insertions(+), 13 deletions(-) diff --git a/init_functions b/init_functions index 7dd0968..33a749f 100644 --- a/init_functions +++ b/init_functions @@ -117,23 +117,12 @@ default_mount_handler() { msg "Trying to continue (this will most likely fail) ..." fi fi - # We didn't build filesystem support into busybox, - # instead we use util-linux's blkid for best compatibility - fstype=${rootfstype:-$(blkid -u filesystem -o value -s TYPE -p "$root")} - if [ -z "$fstype" ]; then - err "Unable to determine the file system type of ${root}:" - echo "Either it contains no filesystem, an unknown filesystem," - echo "or more than one valid file system signature was found." - echo - echo "Try adding" - echo " rootfstype=your_filesystem_type" - echo "to the kernel command line." - echo + + if ! mount ${fstype:+-t $fstype} -o ${rwopt:-ro}${rootflags:+,$rootflags} "$root" "$1"; then echo "You are now being dropped into an emergency shell." launch_interactive_shell msg "Trying to continue (this will most likely fail) ..." fi - mount ${fstype:+-t $fstype} -o ${rwopt:-ro}${rootflags:+,$rootflags} "$root" "$1" } # vim: set ft=sh ts=4 sw=4 et: diff --git a/install/base b/install/base index 1f2b3b8..3d18fe0 100644 --- a/install/base +++ b/install/base @@ -8,6 +8,9 @@ build() { add_binary /lib/initcpio/busybox /bin/busybox add_binary /sbin/modprobe add_binary /sbin/blkid + add_binary /bin/mount + + add_symlink "/etc/mtab" "/proc/self/mounts" add_file "/lib/initcpio/init_functions" "/init_functions" add_file "/lib/initcpio/init" "/init" -- 1.7.7.3
On Sat, Nov 12, 2011 at 1:55 PM, Dave Reisner <d@falconindy.com> wrote:
Providing this means we no longer need blkid for FS detection, as mount will do this for us. Adds a slight bloat to the image, in exchange for a huge convenience. Messaging is changed to assume that /bin/mount will provide useful feedback for us on failure.
Signed-off-by: Dave Reisner <dreisner@archlinux.org>
As long as the bloat is not measured in megabytes it is irrelevant, so this seems like a great step forward. Acked-by: Tom Gundersen <teg@jklm.no>
Am 12.11.2011 03:55, schrieb Dave Reisner:
Providing this means we no longer need blkid for FS detection, as mount will do this for us. Adds a slight bloat to the image, in exchange for a huge convenience. Messaging is changed to assume that /bin/mount will provide useful feedback for us on failure.
Once we start going down this road (cp, mount, ...), wouldn't it be better to simply drop busybox?
On Sat, Nov 12, 2011 at 02:32:09PM +0100, Thomas Bächler wrote:
Am 12.11.2011 03:55, schrieb Dave Reisner:
Providing this means we no longer need blkid for FS detection, as mount will do this for us. Adds a slight bloat to the image, in exchange for a huge convenience. Messaging is changed to assume that /bin/mount will provide useful feedback for us on failure.
Once we start going down this road (cp, mount, ...), wouldn't it be better to simply drop busybox?
Hmm... we're probably close to that point. In terms of size for the tradeoff, we'd need (at a minimum) the following binaries to replace busybox: KB /bin/bash 733896 /bin/mknod 31176 /bin/sleep 27048 /bin/mkdir 47688 /usr/bin/env 27064 /sbin/switch_root 24648 /bin/grep 134600 <-- id prefer to get rid of this /usr/bin/stat 72456 /bin/umount 265568 Someone will throw tomatoes at me for using Bash, but Dash sucks, and it makes a truly awful interactive shell. Additionally, a lot of users would end up bringing in: /usr/bin/setfont 39800 /usr/bin/kbd_mode 10400 cat, sed, rm, and cut are used in crypt/lvm/mdadm hooks. I can refactor some of that out, but that seems to me like it's liable to break hooks that I don't know about. I guess they can BYO via the BINARIES= declare in the build function, but let's just consider having them as core for funzies: /bin/cat 47784 /bin/sed 69184 /bin/cut 39432 /bin/rm 55912 shutdown features necessitate cp /bin/cp 121880 To make the ramfs useful for troubleshooting, add in: /bin/ls 105832 /bin/vi 228096 Ditching busybox and adding in all of this brings in an additional 1.6MB before library dependencies... /lib/libacl.so.1 31856 /lib/libattr.so.1 17248 /lib/libcap.so.2 17096 /lib/libdl.so.2 14704 /lib/libncursesw.so.5 378816 /lib/libpcre.so.0 371160 <- belongs to grep /lib/libreadline.so.6 326762 ...an additional 1.1MB. I point out that we should get rid of grep because awk from FreeBSD is roughly the size of the grep binary, does more, and has zero dependencies beyond libc. My pacman-dev hat wants this in the repos anyways for easier testing of makepkg. I don't have a problem with this -- in the end it'll make my life easier. dave
On 11/12/2011 12:19 PM, Dave Reisner wrote:
On Sat, Nov 12, 2011 at 02:32:09PM +0100, Thomas Bächler wrote:
Am 12.11.2011 03:55, schrieb Dave Reisner:
Providing this means we no longer need blkid for FS detection, as mount will do this for us. Adds a slight bloat to the image, in exchange for a huge convenience. Messaging is changed to assume that /bin/mount will provide useful feedback for us on failure. Once we start going down this road (cp, mount, ...), wouldn't it be better to simply drop busybox?
Hmm... we're probably close to that point. In terms of size for the tradeoff, we'd need (at a minimum) the following binaries to replace busybox: KB /bin/bash 733896 /bin/mknod 31176 /bin/sleep 27048 /bin/mkdir 47688 /usr/bin/env 27064 /sbin/switch_root 24648 /bin/grep 134600<-- id prefer to get rid of this /usr/bin/stat 72456 /bin/umount 265568
Someone will throw tomatoes at me for using Bash, but Dash sucks, and it makes a truly awful interactive shell.
Additionally, a lot of users would end up bringing in:
/usr/bin/setfont 39800 /usr/bin/kbd_mode 10400
cat, sed, rm, and cut are used in crypt/lvm/mdadm hooks. I can refactor some of that out, but that seems to me like it's liable to break hooks that I don't know about. I guess they can BYO via the BINARIES= declare in the build function, but let's just consider having them as core for funzies:
/bin/cat 47784 /bin/sed 69184 /bin/cut 39432 /bin/rm 55912
shutdown features necessitate cp
/bin/cp 121880
To make the ramfs useful for troubleshooting, add in:
/bin/ls 105832 /bin/vi 228096
Ditching busybox and adding in all of this brings in an additional 1.6MB before library dependencies...
/lib/libacl.so.1 31856 /lib/libattr.so.1 17248 /lib/libcap.so.2 17096 /lib/libdl.so.2 14704 /lib/libncursesw.so.5 378816 /lib/libpcre.so.0 371160<- belongs to grep /lib/libreadline.so.6 326762
...an additional 1.1MB. I point out that we should get rid of grep because awk from FreeBSD is roughly the size of the grep binary, does more, and has zero dependencies beyond libc. My pacman-dev hat wants this in the repos anyways for easier testing of makepkg.
I don't have a problem with this -- in the end it'll make my life easier.
dave Good I am also in plans to add "mount" from util-linux in archiso hook.
If busybox is removed, then "dd", "mknod(*)" and "losetup" for archiso. There is a work-in-progress in util-linux that uses the new "/dev/loop-control" from linux-3.1 (for now only works in mount cmd) -- Gerardo Exequiel Pozzi \cos^2\alpha + \sin^2\alpha = 1
On 11/12/2011 12:19 PM, Dave Reisner wrote:
On Sat, Nov 12, 2011 at 02:32:09PM +0100, Thomas Bächler wrote:
Am 12.11.2011 03:55, schrieb Dave Reisner:
Providing this means we no longer need blkid for FS detection, as mount will do this for us. Adds a slight bloat to the image, in exchange for a huge convenience. Messaging is changed to assume that /bin/mount will provide useful feedback for us on failure. Once we start going down this road (cp, mount, ...), wouldn't it be better to simply drop busybox?
Hmm... we're probably close to that point. In terms of size for the tradeoff, we'd need (at a minimum) the following binaries to replace busybox: KB /bin/bash 733896
Someone will throw tomatoes at me for using Bash, but Dash sucks, and it makes a truly awful interactive shell.
Note that, if you want interactive ash shell, just open another vt (execute openvt then switch to it ALT+F2), to use a normal tty console instead of /dev/console. -- Gerardo Exequiel Pozzi \cos^2\alpha + \sin^2\alpha = 1
Signed-off-by: Dave Reisner <dreisner@archlinux.org> --- init_functions | 6 +++++- 1 files changed, 5 insertions(+), 1 deletions(-) diff --git a/init_functions b/init_functions index 33a749f..ff21b42 100644 --- a/init_functions +++ b/init_functions @@ -74,7 +74,7 @@ parse_cmdline() { done } -default_mount_handler() { +resolve_device() { # resolve tag name to block device if [ "${root:0:5}" = 'UUID=' ] || [ "${root:0:6}" = 'LABEL=' ]; then device=$(blkid -l -t "$root" -o device) @@ -117,6 +117,10 @@ default_mount_handler() { msg "Trying to continue (this will most likely fail) ..." fi fi +} + +default_mount_handler() { + resolve_device if ! mount ${fstype:+-t $fstype} -o ${rwopt:-ro}${rootflags:+,$rootflags} "$root" "$1"; then echo "You are now being dropped into an emergency shell." -- 1.7.7.3
This allows a caller to pass in a device by name and get a /dev node returned. Note that this is heavily limited in that only the root device can be identified by major:minor. This might break init's API, if such a thing exists. Signed-off-by: Dave Reisner <dreisner@archlinux.org> --- init_functions | 90 ++++++++++++++++++++++++++++++------------------------- 1 files changed, 49 insertions(+), 41 deletions(-) diff --git a/init_functions b/init_functions index ff21b42..85c1344 100644 --- a/init_functions +++ b/init_functions @@ -75,54 +75,62 @@ parse_cmdline() { } resolve_device() { - # resolve tag name to block device - if [ "${root:0:5}" = 'UUID=' ] || [ "${root:0:6}" = 'LABEL=' ]; then - device=$(blkid -l -t "$root" -o device) - if [ -n "$device" ]; then - root=$device - fi - unset device - fi + local major minor dev device=$1 - if [ ${root:0:5} != "/dev/" ] || ! poll_device "${root}" ${rootdelay}; then - msg "Root device '${root}' doesn't exist. Attempting to create it." - major="" - minor="" - if [ ${devtmpfs_mounted} -eq 0 -a ${root:0:5} = "/dev/" ]; then - # It might be a block device (/dev/sda) -> /sys/class/block/sda/dev - if [ -e /sys/class/block/${root:5}/dev ]; then - IFS=':' read major minor < "/sys/class/block/${root:5}/dev" - break + case $device in + # resolve tag name to block device + UUID=*|LABEL=*) + dev=$(blkid -lt "$device" -o device) + [ -n "$device" ] && device=$dev + ;; + esac + + case $device in + /dev/*) + if poll_device "$device" "$rootdelay"; then + echo "$device" + return 0 fi - # It might be a major/minor pair (8:1) - elif [ "$root" != "${root/:}" ]; then - major="$(echo ${root} | cut -d: -f1)" - minor="$(echo ${root} | cut -d: -f2)" - root="/dev/root" - # It might be major/minor encoded as a single hex-number (lilo-style) (801) - elif [ ${#root} -le 4 -a ${#root} -gt 2 -a -z "${root//[0-9a-fA-F]}" ]; then - str_offset=$((${#root}-2)) - major=$((0x${root:0:${str_offset}})) - minor=$((0x${root:${str_offset}})) - root="/dev/root" - fi - if [ -n "${major}" -a -n "${minor}" ]; then - msg "Creating root device ${root} with major ${major} and minor ${minor}." - mknod ${root} b ${major} ${minor} - else - err "Unable to determine major/minor number of root device '${root}'." - echo "You are being dropped to a recovery shell" - echo " Type 'exit' to try and continue booting" - launch_interactive_shell - msg "Trying to continue (this will most likely fail) ..." - fi + + # block device, e.g. (/dev/sda1) -> /sys/class/block/sda1/dev + if [ -e /sys/class/block/${device:5}/dev ]; then + IFS=':' read major minor < "/sys/class/block/${device:5}/dev" + fi + ;; + [0-9a-fA-F][0-9a-fA-F][0-9a-fA-F]|[0-9a-fA-F][0-9a-fA-F][0-9a-fA-F][0-9a-fA-F]) + # hex encoded major/minor, such as from LILO + major=$(( 0x0$device >> 8 )) + minor=$(( 0x0$device & 0xff )) + ;; + 0x[0-9a-fA-F][0-9a-fA-F]*) + major=$(( $device >> 8 )) + minor=$(( $device & 0xff )) + ;; + esac + + if [ -n "$major" -a -n "$minor" ]; then + device=/dev/root + msg "Creating device node with major $major and minor $minor." + mknod "$device" b "$major" "$minor" + echo "$device" + return 0 fi + + return 1 } default_mount_handler() { - resolve_device + local rootdev + + if ! rootdev=$(resolve_device "$root"); then + err "Unable to determine major/minor number of root device '$root'." + echo "You are being dropped to a recovery shell" + echo " Type 'exit' to try and continue booting" + launch_interactive_shell + msg "Trying to continue (this will most likely fail) ..." + fi - if ! mount ${fstype:+-t $fstype} -o ${rwopt:-ro}${rootflags:+,$rootflags} "$root" "$1"; then + if ! mount ${fstype:+-t $fstype} -o ${rwopt:-ro}${rootflags:+,$rootflags} "$rootdev" "$1"; then echo "You are now being dropped into an emergency shell." launch_interactive_shell msg "Trying to continue (this will most likely fail) ..." -- 1.7.7.3
This adds support for fsck'ing root at bootstrap if the fsck binary and necessary helpers are included. Signed-off-by: Dave Reisner <dreisner@archlinux.org> --- init | 15 +++++++++++++++ init_functions | 22 ++++++++++++++++++---- 2 files changed, 33 insertions(+), 4 deletions(-) diff --git a/init b/init index 975368b..30677de 100644 --- a/init +++ b/init @@ -78,6 +78,21 @@ if [ "${break}" = "y" ] || [ "${break}" = "premount" ]; then launch_interactive_shell fi +rootdev=$(resolve_device "$root") && root=$rootdev +unset rootdev + +if [ -z "$skipfsck" ]; then + fsck_device "$root" + fsckret=$? + if [ "$fsckret" -ne 255 ]; then + if [ $(( $fsckret & 2 )) -eq 2 ]; then + msg "***** reboot required *****" + launch_interactive_shell --exec + fi + echo "$fsckret" > /run/initramfs/root-fsck + fi +fi + # Mount root at /new_root ${mount_handler:-default_mount_handler} /new_root diff --git a/init_functions b/init_functions index 85c1344..62c6af7 100644 --- a/init_functions +++ b/init_functions @@ -58,6 +58,9 @@ parse_cmdline() { fi [ "$lhs" = "${lhs//[^0-9a-zA-Z]}" ] && [ "$lhs" = "${lhs#[0-9]}" ] && eval ${lhs}=\${rhs} ;; + forcefsck) + FORCEFSCK="-f" + ;; *) lhs=${w//[-.]/_} [ "$lhs" = "${lhs//[^0-9a-zA-Z]}" ] && [ "$lhs" = "${lhs#[0-9]}" ] && eval ${lhs}=y ;; @@ -74,6 +77,19 @@ parse_cmdline() { done } +fsck_device() { + [ -x /sbin/fsck ] || return 255 + + if [ ! -b "$1" ]; then + err "device '$1' not found. Skipping fsck." + return 255 + fi + + msg ":: performing fsck on '$1'" + FSTAB_FILE=/dev/null fsck -Ta -C"$FSCK_FD" "$1" -- $FORCEFSCK +} + + resolve_device() { local major minor dev device=$1 @@ -120,9 +136,7 @@ resolve_device() { } default_mount_handler() { - local rootdev - - if ! rootdev=$(resolve_device "$root"); then + if [ ! -b "$root" ]; then err "Unable to determine major/minor number of root device '$root'." echo "You are being dropped to a recovery shell" echo " Type 'exit' to try and continue booting" @@ -130,7 +144,7 @@ default_mount_handler() { msg "Trying to continue (this will most likely fail) ..." fi - if ! mount ${fstype:+-t $fstype} -o ${rwopt:-ro}${rootflags:+,$rootflags} "$rootdev" "$1"; then + if ! mount ${fstype:+-t $fstype} -o ${rwopt:-ro}${rootflags:+,$rootflags} "$root" "$1"; then echo "You are now being dropped into an emergency shell." launch_interactive_shell msg "Trying to continue (this will most likely fail) ..." -- 1.7.7.3
Provides /sbin/fsck and any helper binaries to the image. If processed after the autodetect hook, only the helper for the root FS is added. Signed-off-by: Dave Reisner <dreisner@archlinux.org> --- install/fsck | 28 ++++++++++++++++++++++++++++ 1 files changed, 28 insertions(+), 0 deletions(-) create mode 100644 install/fsck diff --git a/install/fsck b/install/fsck new file mode 100644 index 0000000..a2f538d --- /dev/null +++ b/install/fsck @@ -0,0 +1,28 @@ +#!/bin/bash + +build() { + add_binary /sbin/fsck + + if (( ! fs_autodetect_failed )) && [[ $rootfstype ]]; then + add_binary /sbin/fsck.$rootfstype + else + ( + shopt -s nullglob + for fsck in "$BASEDIR"/sbin/fsck.*; do + add_binary "${fsck#$BASEDIR}" + done + ) + fi +} + +help() { + cat <<HELPEOF +This hook provides fsck and filesystem specific helpers to perform an fsck +operation on the root device prior to mounting. If the autodetect hook is used, +only the fsck helper specific to your filesystem will be added to the image. It +is highly recommended that if you include this hook that you also include any +necessary modules to ensure your keyboard will work in early userspace. +HELPEOF +} + +# vim: set ft=sh ts=4 sw=4 et: -- 1.7.7.3
participants (5)
-
C Anthony Risinger
-
Dave Reisner
-
Gerardo Exequiel Pozzi
-
Thomas Bächler
-
Tom Gundersen