projects/aports·blob master · refs

160 lines · 4.0 KiB

1#!/sbin/openrc-run
2
3# Copyright (c) Natanael Copa
4# This code is licensed under BSD-2-Clause
5
6# script that will mount image with modules
7
8depend() {
9 after dev-mount
10 before checkfs fsck hwdrivers modules hwclock dev sysfs
11 keyword -vserver -lxc
12}
13
14# read kernel options
15init_KOPT() {
16 for opt in $(cat /proc/cmdline 2>/dev/null); do
17 case "$opt" in
18 modloop=*|modloop_verify=*)
19 eval "KOPT_${opt%%=*}='${opt#*=}'" ;;
20 esac
21 done
22}
23
24mountdirs() {
25 awk '$2 !~ /^\/(sys|proc|dev|run)/ && $2 != "/" {print $2}' /proc/mounts
26}
27
28find_modloop() {
29 local dir="$1"
30 local kver=$(uname -r)
31 local oifs="$IFS"
32 IFS=$'\n'
33 set -- $(blkid "$dir"/boot/* "$dir"/*)
34 IFS="$oifs"
35 for line; do
36 img=${line%%:*}
37 verify_modloop "$img" || eerror "Failed to verify signature of $img!"
38 mount "$img" -o loop,ro /.modloop || continue
39 if [ -d /.modloop/modules/$kver ]; then
40 return 0
41 fi
42 umount /.modloop
43 done
44 return 1
45}
46
47verify_modloop() {
48 local modloop=$1 key=
49 if ! yesno "${KOPT_modloop_verify:=yes}"; then
50 return 0
51 fi
52 for key in /etc/apk/keys/*.pub; do
53 local sig=/var/cache/misc/${modloop##*/}.SIGN.RSA.${key##*/}
54 if [ -f "$sig" ]; then
55 if ! command -v openssl > /dev/null; then
56 ewarn "Missing openssl. Modloop verification disabled!"
57 return 0
58 fi
59 einfo "Verifying modloop"
60 openssl dgst -sha1 -verify "$key" -signature "$sig" "$modloop" \
61 >/dev/null 2>&1 || return 1
62 fi
63 done
64}
65
66find_backing_file() {
67 local dir="$1"
68 local dev=$(df -P "$dir" | tail -1 | awk '{print $1}')
69 cat /sys/block/${dev#/dev/}/loop/backing_file 2>/dev/null
70}
71
72start() {
73 local modloop= mount_opts= modloop_dldir="/lib"
74 init_KOPT
75
76 case "$KOPT_modloop" in
77 none) return 0;;
78 http://*|https://*|ftp://*)
79 modloop=$modloop_dldir/${KOPT_modloop##*/}
80 if [ ! -f "$modloop" ]; then
81 mkdir -p "$modloop_dldir"
82 wget -P "$modloop_dldir" "$KOPT_modloop" || eend 1
83 fi
84 ;;
85 *)
86 for dir in $(mountdirs); do
87 if [ -f "$dir"/$KOPT_modloop ]; then
88 modloop="$dir/${KOPT_modloop##/}"
89 alpine_mnt="$dir"
90 break
91 fi
92 done
93 ;;
94 esac
95
96 ebegin "Mounting modloop $modloop"
97 mkdir -p /.modloop
98 if [ -n "$modloop" ]; then
99 verify_modloop "$modloop" || eerror "Failed to verify signature of $modloop!"
100 mount -o loop,ro $modloop /.modloop
101 eend $? || return 1
102 else
103 for dir in $(mountdirs); do
104 if find_modloop "$dir"; then
105 alpine_mnt="$dir"
106 break
107 fi
108 done
109 if [ -d /.modloop/modules/$(uname -r) ]; then
110 eend 0
111 else
112 eend 1 || return 1
113 fi
114 fi
115
116 #use overlayfs if available and configured
117 if grep -q -w "overlay$" /proc/filesystems && [ ! -z ${unionfs_size+x} ]; then
118 ewarn "Use of unionfs_size is deprecated use overlay_size instead"
119 overlay_size="$unionfs_size"
120 fi
121 if grep -q -w "overlay$" /proc/filesystems && [ -n "$overlay_size" ]; then
122 ebegin "OverlayFS detected, mounting modloop rw"
123 [ "$overlay_size" != 0 ] && mount_ops="-o size=$overlay_size"
124 mkdir -p /.modoverlayfs /lib/modules
125 mount -t tmpfs $mount_ops tmpfs /.modoverlayfs
126 mkdir -p /.modoverlayfs/modules /.modoverlayfs/work
127 mount -t overlay -o upperdir=/.modoverlayfs/modules,lowerdir=/lib/modules:/.modloop/modules,workdir=/.modoverlayfs/work overlay /lib/modules
128 depmod -A
129 eend $? || return 1
130 else
131 rm -rf /lib/modules && ln -sf /.modloop/modules /lib/
132 fi
133
134 # symlink firmware files
135 mkdir -p /lib/firmware
136 [ -z "$(ls -A /lib/firmware)" ] && [ -d /lib/modules/firmware ] && ln -s /lib/modules/firmware/* /lib/firmware/ 2>/dev/null
137 if [ -d $alpine_mnt/firmware ]; then
138 ebegin "Linking firmware from $alpine_mnt/firmware on top"
139 ln -sf $alpine_mnt/firmware/* /lib/firmware/ 2>/dev/null
140 eend $?
141 fi
142 return 0
143}
144
145stop() {
146 local ret=0
147 local mnt; for mnt in /lib/modules /.modoverlayfs /.modloop; do
148 if mountinfo --quiet "$mnt"; then
149 ebegin "Unmounting $mnt"
150 umount -d "$mnt" || ret=1
151 fi
152 done
153
154 # cleanup orphaned symlinks from modloop
155 find /lib/firmware -maxdepth 1 -type l -exec sh -c 'readlink "$0" | grep -q "^/lib/modules/firmware" && rm "$0"' {} \;
156 [ "$( readlink /lib/modules )" = "/.modloop/modules" ] && rm /lib/modules
157
158 eend $ret || return 1
159}
160