aboutsummaryrefslogtreecommitdiffstats
path: root/main/openrc/modloop.initd
blob: 97a45cc19a0326560d98c41c3c43d25ca704c0ee (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
129
130
131
132
133
134
135
136
137
138
#!/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
	[ -z "$KOPT_alpine_dev" ] && return 0
	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= modloop_mounted=
	find_media
	if [ -z "$alpine_dev" ] ; then
		return 0
	fi

	if [ -z "$alpine_mounted" ]; then
		ebegin "Mounting $alpine_mnt"
		[ -n "$alpine_fs" ] && mount_opts="-t $alpine_fs"
		mount $mount_opts /dev/$alpine_dev $alpine_mnt 2>/dev/null
		eend $? || return 1
	fi
	mkdir -p /.modloop /lib

	for modloop in ${alpine_mnt}$KOPT_modloop \
			${alpine_mnt}$KOPT_BOOT_IMAGE.modloop.* \
			${alpine_mnt}$KOPT_BOOT_IMAGE.cmg; do
		[ -f "$modloop" ] || continue
		ebegin "Mounting modloop $modloop"
		mount -o loop,ro $fs_opt $modloop /.modloop \
			&& modloop_mounted=1
		eend $? || return 1
	done
	[ "$modloop_mounted" = "1" ] || 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
	return 0
}

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