mirror of
https://gitlab.alpinelinux.org/alpine/abuild.git
synced 2024-12-25 00:12:19 +00:00
e047051e5d
sometimes it is possible to manually fix the problem, for example mount the alpine device manually after modprobing the correct modules. Then it makes sense to continue boot rather than just die.
306 lines
6.8 KiB
Plaintext
Executable File
306 lines
6.8 KiB
Plaintext
Executable File
#!/bin/busybox sh
|
|
|
|
# this is the init script version
|
|
VERSION=1.1
|
|
NEWROOT=/newroot
|
|
SINGLEMODE=no
|
|
|
|
/bin/busybox --install -s
|
|
|
|
# basic environment
|
|
export PATH=/usr/bin:/bin:/usr/sbin:/sbin
|
|
|
|
# needed devs
|
|
[ -c /dev/null ] || mknod -m 666 /dev/null c 1 3
|
|
|
|
# basic mounts
|
|
mount -t proc -o noexec,nosuid,nodev proc /proc
|
|
mount -t sysfs -o noexec,nosuid,nodev sysfs /sys
|
|
|
|
# some helpers
|
|
ebegin() {
|
|
echo -n " * $*: "
|
|
}
|
|
eend() {
|
|
local msg
|
|
if [ "$1" = 0 ] || [ $# -lt 1 ] ; then
|
|
echo "ok."
|
|
else
|
|
shift
|
|
echo "failed. $*"
|
|
echo "initramfs emergency recovery shell launched. Type 'exit' to continue boot"
|
|
/bin/busybox sh
|
|
fi
|
|
}
|
|
|
|
scan_drivers() {
|
|
if [ "$AUTODETECT" != no ] ; then
|
|
find /sys -name modalias | xargs sort -u | xargs modprobe -a 2> /dev/null
|
|
fi
|
|
}
|
|
|
|
find_ovl() {
|
|
local mnt="$1"
|
|
local ovl
|
|
local lines
|
|
|
|
# look for apkovl's on mounted media
|
|
ovl=$( ls -1 "$mnt"/*.apkovl.tar.gz* 2>/dev/null ) || return 1
|
|
lines=$(echo "$ovl" | wc -l)
|
|
|
|
if [ $lines -gt 1 ] ; then
|
|
echo "ERROR: More than one apkovl file was found on $(basename $mnt). None will be read." >&2
|
|
return 1
|
|
fi
|
|
echo "$ovl"
|
|
}
|
|
|
|
retry_mount() {
|
|
# usb might need some time to settle so we retry a few times
|
|
for i in $(seq 0 19); do
|
|
mount $@ 2>&1 && return 0
|
|
sleep 1
|
|
done
|
|
return 1
|
|
}
|
|
|
|
unpack_apkovl() {
|
|
local ovl="$1"
|
|
local dest="$2"
|
|
local suffix=${ovl##*.}
|
|
local i
|
|
if [ "$suffix" = "gz" ]; then
|
|
tar -C "$dest" -zxf "$ovl"
|
|
return $?
|
|
fi
|
|
|
|
for i in $ALPINE_MNT/*/*/openssl-[0-9]*.apk $ALPINE_MNT/*/openssl-[0-9]*.apk; do
|
|
[ -f "$i" ] && tar -C / -zxf $i && break
|
|
done
|
|
|
|
if ! openssl list-cipher-commands | grep "^$suffix$" > /dev/null; then
|
|
errstr="Cipher $suffix is not supported"
|
|
return 1
|
|
fi
|
|
local count=0
|
|
# beep
|
|
echo -e "\007"
|
|
while [ $count -lt 3 ]; do
|
|
openssl enc -d -$suffix -in "$ovl" | tar -C "$dest" -zx \
|
|
2>/dev/null && return 0
|
|
count=$(( $count + 1 ))
|
|
done
|
|
return 1
|
|
}
|
|
|
|
# gotta start from somewhere :)
|
|
echo "Alpine Init $VERSION"
|
|
|
|
# read the kernel options
|
|
for i in `cat /proc/cmdline` ; do
|
|
case $i in
|
|
s|single|1)
|
|
SINGLEMODE=yes ;;
|
|
modules=*)
|
|
MODULES="`echo ${i#modules=} | tr ',' ' '`";;
|
|
noautodetect)
|
|
AUTODETECT=no;;
|
|
*=*) eval KOPT_$i ;;
|
|
*) eval KOPT_$i=yes ;;
|
|
esac
|
|
done
|
|
|
|
# start bootcharting if wanted
|
|
if [ -n "$KOPT_chart" ]; then
|
|
ebegin "Starting bootchart logging"
|
|
/sbin/bootchartd start-initfs "$NEWROOT"
|
|
eend 0
|
|
fi
|
|
|
|
ALPINE_DEV=${KOPT_alpine_dev%%:*}
|
|
ALPINE_DEV_FS=${KOPT_alpine_dev##*:}
|
|
if [ "$ALPINE_DEV_FS" = "$ALPINE_DEV" ]; then
|
|
unset ALPINE_DEV_FS
|
|
fi
|
|
ALPINE_MNT=/media/$ALPINE_DEV
|
|
|
|
# hide kernel messages
|
|
dmesg -n 1
|
|
|
|
# setup /dev
|
|
ebegin "Starting mdev"
|
|
mount -t tmpfs -o exec,nosuid,mode=0755 mdev /dev
|
|
ln -s sr0 /dev/cdrom
|
|
echo "/sbin/mdev" > /proc/sys/kernel/hotplug
|
|
mdev -s
|
|
RC=$?
|
|
[ -d /dev/pts ] || mkdir -m 755 /dev/pts
|
|
[ -c /dev/ptmx ] || mknod -m 666 /dev/ptmx c 5 2
|
|
mount -t devpts -o gid=5,mode=0620,noexec,nosuid devpts /dev/pts
|
|
[ -d /dev/shm ] || mkdir /dev/shm
|
|
mount -t tmpfs -o nodev,nosuid,noexec shm /dev/shm
|
|
eend $RC
|
|
|
|
# load available drivers to get access to modloop media
|
|
ebegin "Loading boot drivers"
|
|
[ "$MODULES" ] && modprobe -a $MODULES 2> /dev/null
|
|
if [ -f /etc/modules ] ; then
|
|
sed 's/\#.*//g' < /etc/modules |
|
|
while read module args; do
|
|
modprobe -q $module $args
|
|
done
|
|
fi
|
|
scan_drivers
|
|
scan_drivers
|
|
eend 0
|
|
|
|
# check if root=... was set
|
|
if [ -n "$KOPT_root" ]; then
|
|
if [ "$SINGLEMODE" = "yes" ]; then
|
|
echo "Entering single mode. Type 'exit' to continue booting."
|
|
sh
|
|
fi
|
|
case "$KOPT_root" in
|
|
/dev/md*)
|
|
mknod $KOPT_root b 9 ${KOPT_root#/dev/md}
|
|
raidautorun "$KOPT_root"
|
|
;;
|
|
esac
|
|
ebegin "Mounting root"
|
|
retry_mount $KOPT_root $NEWROOT 2>/dev/null
|
|
eend $?
|
|
cat /proc/mounts | while read DEV DIR TYPE OPTS ; do
|
|
if [ "$DIR" != "/" -a "$DIR" != "$NEWROOT" -a -d "$DIR" ]; then
|
|
mkdir -p $NEWROOT/$DIR
|
|
mount -o move $DIR $NEWROOT/$DIR
|
|
fi
|
|
done
|
|
sync
|
|
exec /bin/busybox switch_root $NEWROOT $chart_init /sbin/init $KOPT_init_args
|
|
echo "initramfs emergency recovery shell launched"
|
|
exec /bin/busybox sh
|
|
fi
|
|
|
|
# locate boot media and mount it
|
|
ebegin "Mounting boot media"
|
|
mkdir -p $ALPINE_MNT
|
|
if [ -n "$ALPINE_DEV_FS" ]; then
|
|
mount_opts="-t $ALPINE_DEV_FS"
|
|
fi
|
|
|
|
retry_mount $mount_opts /dev/$ALPINE_DEV $ALPINE_MNT >/dev/null 2>&1
|
|
eend $?
|
|
|
|
ebegin "Mounting loopback device for kernel modules"
|
|
modprobe loop
|
|
if [ -n "$KOPT_modloop" ]; then
|
|
modloop=$KOPT_modloop
|
|
else
|
|
modloop=$KOPT_BOOT_IMAGE.cmg
|
|
fi
|
|
mount -o loop,ro -t cramfs $ALPINE_MNT/$modloop /.modloop
|
|
rc=$?
|
|
if [ "$rc" = 0 ]; then
|
|
rm -rf /lib/modules
|
|
ln -sf /.modloop/modules /lib
|
|
fi
|
|
eend $?
|
|
|
|
if [ -d $ALPINE_MNT/firmware ]; then
|
|
ebegin "Copying firmware from $ALPINE_MNT/firmware"
|
|
mkdir -p /lib
|
|
cp -R -a $ALPINE_MNT/firmware /lib/
|
|
eend $?
|
|
fi
|
|
|
|
mkdir -p /etc/apk
|
|
for i in $ALPINE_MNT/*/APK_INDEX.gz $ALPINE_MNT/*/*/APK_INDEX.gz; do
|
|
[ -r "$i" ] && echo ${i%/APK_INDEX.gz} >> /etc/apk/repositories
|
|
done
|
|
|
|
# early console?
|
|
if [ "$SINGLEMODE" = "yes" ]; then
|
|
echo "Entering single mode. Type 'exit' to continue booting."
|
|
sh
|
|
fi
|
|
|
|
# more drivers
|
|
ebegin "Loading hardware drivers"
|
|
scan_drivers
|
|
eend 0
|
|
|
|
mount -t tmpfs tmpfs $NEWROOT
|
|
|
|
# look for apkovl
|
|
if dmesg | grep '^usb-storage: waiting' >/dev/null; then
|
|
ebegin "Waiting for USB device to settle"
|
|
while ! dmesg | grep 'usb-storage: device scan complete' >/dev/null; do
|
|
sleep 1
|
|
done
|
|
eend 0
|
|
fi
|
|
for i in usb floppy cdrom; do
|
|
mount /media/$i 2>/dev/null || continue
|
|
ovl=$(find_ovl /media/$i)
|
|
[ -f "$ovl" ] && break
|
|
umount /media/$i 2>/dev/null
|
|
done
|
|
if ! [ -f "$ovl" ]; then
|
|
ovl=$(find_ovl $ALPINE_MNT)
|
|
fi
|
|
|
|
if [ -f "$ovl" ]; then
|
|
ebegin "Loading user settings from $ovl"
|
|
unpack_apkovl "$ovl" $NEWROOT
|
|
eend $? $errstr
|
|
umount /media/$i 2>/dev/null &
|
|
pkgs=$(sed 's/\#.*//' $NEWROOT/etc/lbu/packages.list 2>/dev/null)
|
|
fi
|
|
|
|
# install new root
|
|
ebegin "Installing packages to root filesystem"
|
|
if [ -n "$KOPT_chart" ]; then
|
|
pkgs="$pkgs acct"
|
|
fi
|
|
apkflags="--initdb --quiet --progress --force"
|
|
if [ -z "$KOPT_keep_apk_new" ]; then
|
|
apkflags="$apkflags --clean-protected"
|
|
fi
|
|
apk add --root /newroot $apkflags $pkgs >/dev/null
|
|
eend $?
|
|
|
|
# copy alpine release info
|
|
cp $ALPINE_MNT/.alpine-release $NEWROOT/
|
|
ln -sf /.alpine-release $NEWROOT/etc/alpine-release
|
|
|
|
# if there is no repositories file, then use the default
|
|
if ! [ -f $NEWROOT/etc/apk/repositories ]; then
|
|
cp /etc/apk/repositories $NEWROOT/etc/apk/repositories
|
|
fi
|
|
|
|
# setup bootchart for switch_root
|
|
chart_init=""
|
|
if [ -n "$KOPT_chart" ]; then
|
|
/sbin/bootchartd stop-initfs "$NEWROOT"
|
|
chart_init="/sbin/bootchartd start-rootfs"
|
|
fi
|
|
|
|
# switch over to new root
|
|
cat /proc/mounts | while read DEV DIR TYPE OPTS ; do
|
|
if [ "$DIR" != "/" -a "$DIR" != "$NEWROOT" -a -d "$DIR" ]; then
|
|
mkdir -p $NEWROOT/$DIR
|
|
mount -o move $DIR $NEWROOT/$DIR
|
|
fi
|
|
done
|
|
ln -sf /.modloop/modules $NEWROOT/lib/modules
|
|
sync
|
|
|
|
echo ""
|
|
if [ -x $NEWROOT/sbin/init ]; then
|
|
exec /bin/busybox switch_root $NEWROOT $chart_init /sbin/init $KOPT_init_args
|
|
fi
|
|
|
|
echo "initramfs emergency recovery shell launched"
|
|
exec /bin/busybox sh
|
|
reboot
|