aboutsummaryrefslogtreecommitdiffstats
path: root/main/openrc/modloop.initd
blob: d2cff4e6a3a53c65554abb633aad8c0dec62007b (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
#!/sbin/runscript

# script that will mount image with modules

depend() {
	need dev
	before checkfs fsck hwdrivers modules hwclock
	keyword novserver
}

# read kernel options
init_KOPT() {
	eval set -- $(cat /proc/cmdline 2>/dev/null)
	while [ $# -gt 0 ]; do
	        case "$1" in
                	*=*)    eval "KOPT_${1%%=*}='${1#*=}'" ;;
	                *)      eval "KOPT_$(echo $1 | sed 's: :_:g')=yes" ;;
        	esac
        	shift
	done
}

resolve_dev() {
	case "$1" in
	UUID=*|LABEL=*) findfs "$1";;
	*) readlink -f "$1";;
	esac
}

find_mnt() {
	local search_dev="$1" fstab="$2"
	local dev mnt fs mntopts chk
	case "$search_dev" in
		UUID=*|LABEL=*|/dev/*);;
		*) search_dev=/dev/$search_dev;;
	esac
	local search_real_dev=$(resolve_dev $search_dev)
	while read dev mnt fs mntopts chk; do
		local real_dev=$(resolve_dev $dev)
		local i j
		for i in "$search_dev" "$search_real_dev"; do
			[ -z "$i" ] && continue
			for j in "$dev" "$real_dev"; do
				[ -z "$j" ] && continue
				if [ "$i" = "$j" ]; then
					echo "$mnt"
					return
				fi
			done
		done
	done < $fstab 2>/dev/null
}

# initialies: alpine_dev, alpine_mnt, alpine_fs, alpine_mounted
find_media() {
	init_KOPT
	alpine_mounted=
	alpine_dev=${KOPT_alpine_dev%%:*}
	alpine_fs=${KOPT_alpine_dev#*:}
	[ "$alpine_fs" = "$KOPT_alpine_dev" ] && unset alpine_fs
	# first we check if alpine_dev is mounted and use this
	alpine_mnt=$(find_mnt $alpine_dev /proc/mounts)
	if [ -z "$alpine_mnt" ]; then
		# then we check fstab
		alpine_mnt=$(find_mnt /dev/$alpine_dev /etc/fstab)
	else
		alpine_mounted=yes
	fi
	# finally we fallback to /media/<devicename>
	[ -z "$alpine_mnt" ] && alpine_mnt=/media/$alpine_dev
}

start() {
	local modloop mount_opts
	find_media
	if [ -z "$alpine_dev" ] ; then
		return 0
	fi

        modloop=${KOPT_modloop:-$KOPT_BOOT_IMAGE.cmg}
	[ -n "$alpine_fs" ] && mount_opts="-t $alpine_fs"

	ebegin "Mounting loopback device for kernel modules"
	if [ -z "$alpine_mounted" ]; then
		mount $mount_opts /dev/$alpine_dev $alpine_mnt 2>/dev/null
	fi
	mkdir -p /.modloop /lib

	mount -o loop,ro -t cramfs  $alpine_mnt/$modloop /.modloop
	
	eend $? || return 1
	
	#use unionfs is available and configured
	if grep -q -w "unionfs$" /proc/filesystems && [ -n "$unionfs_size" ]; then
		ebegin "UnionFS detected. Mounting modloop rw"
		mkdir -p /.modunisonfs/modules /lib/modules
		mount -t tmpfs -o size="$unionfs_size" tmpfs /.modunisonfs/modules
		mount -t unionfs -o dirs=/.modunisonfs/modules=rw:/.modloop/modules=ro unionfs /lib/modules
		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
}

stop() {
	local rc=0
	find_media
	[ -z "$alpine_dev" ] && return 0
	ebegin "Unmounting loopback device for kernel modules"
	if mountinfo --quiet /.modloop; then
		umount -d /.modloop || rc=1
	fi
	if mountinfo --quiet $alpine_mnt; then
		umount $alpine_mnt || rc=1
	fi
	eend $rc 
}