aboutsummaryrefslogblamecommitdiffstats
path: root/main/openrc/modloop.initd
blob: 19be59de00f2bcd2dc0f55e52a69d176a0b3e55a (plain) (tree)
1
2
3
4
5
6
7
8





                                           
                                                     
                               




                                                    





                                                                     
                    


            






                                     
            



                                        
                                                           
















                                                             




                                                               
                                             




                                                                
                                                       

                                     
                                                             







                                                             
                                                       
 
                  
 


                                                                  
                                                                                   

                          
                                                     







                                                                                          

                                                          
                                                            
                                        




                                                        
                                                                   


                                                             


                                                                     


                                                                                


                            
 



                                                   
 









                                                                                                           





                                                                   


                                                            
          
                


        
                  

                                        
                                            


                                             

                                              


                                               
          

 
#!/sbin/runscript

# script that will mount image with modules

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

# read kernel options
init_KOPT() {
	eval set -- $(cat /proc/cmdline 2>/dev/null)
	# in case syslinux does not set BOOT_IMAGE
	KOPT_BOOT_IMAGE="${1}"
	for opt; do
	        case "$opt" in
			alpine_dev=*|modloop=*|BOOT_IMAGE=*)
				eval "KOPT_${opt%%=*}='${opt#*=}'" ;;
        	esac
	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/*);;
		nfs) search_dev="${KOPT_alpine_dev#nfs:}";;
		*) 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 $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_dldir="/lib"

	find_media

	case "$KOPT_modloop" in
		http://*|https://|ftp://*)
			wget -P "$modloop_dldir" "$KOPT_modloop" \
				&& modloop=$modloop_dldir/$(basename $KOPT_modloop)
			;;
		*)
			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

			bootimagedir=${KOPT_BOOT_IMAGE%/*}
			bootdir=${alpine_mnt}${bootimagedir}
			kver=$(uname -r)
			case $kver in
			*-rc[0-9]) kflavor=vanilla;;
			*-[a-z]*)  kflavor=${kver##*-};;
			*)         kflavor=vanilla;;
			esac
			for modloop in ${alpine_mnt}$KOPT_modloop \
				${bootdir}/modloop-$kver \
				${bootdir}/modloop-$kflavor \
				${bootdir}/modloop \
				${alpine_mnt}/boot/modloop-$kver \
				${alpine_mnt}/boot/modloop-$kflavor \
				${alpine_mnt}/boot/modloop \
				${alpine_mnt}$KOPT_BOOT_IMAGE.modloop.*; do

				[ -f "$modloop" -o -n "$KOPT_modloop" ] && break
			done
			;;
	esac

	ebegin "Mounting modloop $modloop"
	mkdir -p /.modloop /lib
	mount -o loop,ro $fs_opt $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
	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
}