summaryrefslogtreecommitdiff
path: root/extra/openrc/modloop.initd
diff options
context:
space:
mode:
authordavidovski <david@davidovski.xyz>2022-03-29 23:37:34 +0100
committerdavidovski <david@davidovski.xyz>2022-03-29 23:37:34 +0100
commitd28d2287b138ede0591d9facd5dbe7ca4f329f83 (patch)
treecea79933059dd721d6a9578f6214ac6fe9057d56 /extra/openrc/modloop.initd
parent14a1fee0a54d94f0f57f50d2532849f3c2383a15 (diff)
added sysvinit and openrc
Diffstat (limited to 'extra/openrc/modloop.initd')
-rwxr-xr-xextra/openrc/modloop.initd153
1 files changed, 153 insertions, 0 deletions
diff --git a/extra/openrc/modloop.initd b/extra/openrc/modloop.initd
new file mode 100755
index 0000000..fb7006c
--- /dev/null
+++ b/extra/openrc/modloop.initd
@@ -0,0 +1,153 @@
+#!/sbin/openrc-run
+
+# script that will mount image with modules
+
+depend() {
+ after dev-mount
+ before checkfs fsck hwdrivers modules hwclock dev sysfs
+ keyword -vserver -lxc
+}
+
+# read kernel options
+init_KOPT() {
+ for opt in $(cat /proc/cmdline 2>/dev/null); do
+ case "$opt" in
+ modloop=*|modloop_verify=*)
+ eval "KOPT_${opt%%=*}='${opt#*=}'" ;;
+ esac
+ done
+}
+
+mountdirs() {
+ awk '$2 !~ /^\/(sys|proc|dev|run)/ && $2 != "/" {print $2}' /proc/mounts
+}
+
+find_modloop() {
+ local dir="$1"
+ local kver=$(uname -r)
+ local oifs="$IFS"
+ IFS=$'\n'
+ set -- $(blkid "$dir"/boot/* "$dir"/*)
+ IFS="$oifs"
+ for line; do
+ img=${line%%:*}
+ verify_modloop "$img" || eerror "Failed to verify signature of $img!"
+ mount "$img" -o loop,ro /.modloop || continue
+ if [ -d /.modloop/modules/$kver ]; then
+ return 0
+ fi
+ umount /.modloop
+ done
+ return 1
+}
+
+verify_modloop() {
+ local modloop=$1 key=
+ if ! yesno "${KOPT_modloop_verify:=yes}"; then
+ return 0
+ fi
+ for key in /etc/apk/keys/*.pub; do
+ local sig=/var/cache/misc/${modloop##*/}.SIGN.RSA.${key##*/}
+ if [ -f "$sig" ]; then
+ if ! command -v openssl > /dev/null; then
+ ewarn "Missing openssl. Modloop verification disabled!"
+ return 0
+ fi
+ einfo "Verifying modloop"
+ openssl dgst -sha1 -verify "$key" -signature "$sig" "$modloop" \
+ >/dev/null 2>&1 || return 1
+ fi
+ done
+}
+
+find_backing_file() {
+ local dir="$1"
+ local dev=$(df -P "$dir" | tail -1 | awk '{print $1}')
+ cat /sys/block/${dev#/dev/}/loop/backing_file 2>/dev/null
+}
+
+start() {
+ local modloop= mount_opts= modloop_dldir="/lib"
+ init_KOPT
+
+ case "$KOPT_modloop" in
+ none) return 0;;
+ http://*|https://*|ftp://*)
+ modloop=$modloop_dldir/${KOPT_modloop##*/}
+ if [ ! -f "$modloop" ]; then
+ mkdir -p "$modloop_dldir"
+ wget -P "$modloop_dldir" "$KOPT_modloop" || eend 1
+ fi
+ ;;
+ *)
+ for dir in $(mountdirs); do
+ if [ -f "$dir"/$KOPT_modloop ]; then
+ modloop="$dir/${KOPT_modloop##/}"
+ alpine_mnt="$dir"
+ break
+ fi
+ done
+ ;;
+ esac
+
+ ebegin "Mounting modloop $modloop"
+ mkdir -p /.modloop
+ if [ -n "$modloop" ]; then
+ verify_modloop "$modloop" || eerror "Failed to verify signature of $img!"
+ mount -o loop,ro $modloop /.modloop
+ eend $? || return 1
+ else
+ for dir in $(mountdirs); do
+ if find_modloop "$dir"; then
+ alpine_mnt="$dir"
+ break
+ fi
+ done
+ if [ -d /.modloop/modules/$(uname -r) ]; then
+ eend 0
+ else
+ eend 1 || return 1
+ fi
+ fi
+
+ #use overlayfs if available and configured
+ if grep -q -w "overlay$" /proc/filesystems && [ ! -z ${unionfs_size+x} ]; then
+ ewarn "Use of unionfs_size is deprecated use overlay_size instead"
+ overlay_size="$unionfs_size"
+ fi
+ if grep -q -w "overlay$" /proc/filesystems && [ -n "$overlay_size" ]; then
+ ebegin "OverlayFS detected, mounting modloop rw"
+ [ "$overlay_size" != 0 ] && mount_ops="-o size=$overlay_size"
+ mkdir -p /.modoverlayfs /lib/modules
+ mount -t tmpfs $mount_ops tmpfs /.modoverlayfs
+ mkdir -p /.modoverlayfs/modules /.modoverlayfs/work
+ mount -t overlay -o upperdir=/.modoverlayfs/modules,lowerdir=/lib/modules:/.modloop/modules,workdir=/.modoverlayfs/work overlay /lib/modules
+ depmod -A
+ eend $? || return 1
+ else
+ rm -rf /lib/modules && ln -sf /.modloop/modules /lib/
+ fi
+
+ # copy firmware if there are any
+ if [ -d $alpine_mnt/firmware ]; then
+ ebegin "Copying firmware from $alpine_mnt/firmware"
+ cp -R -a $alpine_mnt/firmware /lib/
+ eend $?
+ elif [ -d /lib/modules/firmware ]; then
+ rmdir /lib/firmware 2>/dev/null \
+ && ln -s /lib/modules/firmware /lib/
+ fi
+ return 0
+}
+
+stop() {
+ local ret=0
+ local mnt; for mnt in /lib/modules /.modoverlayfs /.modloop; do
+ if mountinfo --quiet "$mnt"; then
+ ebegin "Unmounting $mnt"
+ umount -d "$mnt" || ret=1
+ fi
+ done
+ eend $ret || return 1
+}
+