home: hub: mkinitfs

Download patch

ref: 78806300b0dbc8bca010f38222fb4318268317fe
parent: 584a90d42d4a7229410584529f698668d059ffbf
author: Natanael Copa <ncopa@alpinelinux.org>
date: Tue May 9 09:29:04 CDT 2023

init: ensure that mount options in fstab is respected

--- a/initramfs-init.in
+++ b/initramfs-init.in
@@ -62,30 +62,28 @@
 	return 1
 }
 
-# find mount dir for given device in an fstab
-# returns global MNTOPTS
-find_mnt() {
+# find mount dir and mount opts for given device in an fstab
+get_fstab_mount_info() {
 	local search_dev="$1"
 	local fstab="$2"
+	local mntopts=
 	case "$search_dev" in
 	UUID*|LABEL*) search_dev=$(findfs "$search_dev");;
 	esac
-	MNTOPTS=
 	[ -r "$fstab" ] || return 1
 	local search_maj_min=$(stat -L -c '%t,%T' $search_dev)
-	while read dev mnt fs MNTOPTS chk; do
+	while read dev mnt fs mntopts chk; do
 		case "$dev" in
 		UUID*|LABEL*) dev=$(findfs "$dev");;
 		esac
-		if [ -b "$dev" ]; then
+		if [ -b "$dev" ] || [ -n "$ROOT" ]; then
 			local maj_min=$(stat -L -c '%t,%T' $dev)
 			if [ "$maj_min" = "$search_maj_min" ]; then
-				echo "$mnt"
+				echo "$mnt $mntopts"
 				return
 			fi
 		fi
 	done < $fstab
-	MNTOPTS=
 }
 
 #  add a boot service to $sysroot
@@ -227,26 +225,31 @@
 	MAC_ADDRESS=$(cat /sys/class/net/$device/address)
 }
 
-# relocate mountpoint according given fstab
-relocate_mount() {
+# relocate mountpoint according given fstab and set mount options
+remount_fstab_entry() {
 	local fstab="${1}"
 	local dir=
-	if ! [ -e $repofile ]; then
+	if ! [ -e "$repofile" ]; then
 		return
 	fi
-	echo "$ovl" | cat - $repofile | while read dir; do
+	echo "$ovl" | cat - "$repofile" | while read dir; do
 		# skip http(s)/ftp repos for netboot
-		if ! [ -d "$dir" -o -f "$dir" ]; then
+		if [ -z "$dir" ] || ! [ -d "$ROOT/$dir" -o -f "$ROOT/$dir" ]; then
 			continue
 		fi
 		local dev=$(df -P "$dir" | tail -1 | awk '{print $1}')
-		local mnt=$(find_mnt $dev $fstab)
+		local mntinfo="$(get_fstab_mount_info "$dev" "$fstab")"
+		local mnt="${mntinfo% *}"
+		local mntopts="${mntinfo#* }"
 		if [ -n "$mnt" ]; then
-			local oldmnt=$(awk -v d=$dev '$1==d {print $2}' "$ROOT"/proc/mounts 2>/dev/null)
+			local oldmnt=$(awk -v d=$ROOT$dev '$1==d {print $2}' "$ROOT"/proc/mounts 2>/dev/null)
 			if [ "$oldmnt" != "$mnt" ]; then
 				mkdir -p "$mnt"
 				$MOCK mount -o move "$oldmnt" "$mnt"
 			fi
+			if [ -n "$mntopts" ]; then
+				$MOCK mount -o remount,"$mntopts" "$mnt"
+			fi
 		fi
 	done
 }
@@ -605,7 +608,7 @@
 $MOCK nlplug-findfs $cryptopts -p /sbin/mdev ${KOPT_debug_init:+-d} \
 	${KOPT_usbdelay:+-t $(( $KOPT_usbdelay * 1000 ))} \
 	${KOPT_uevent_buf_size:+-U $KOPT_uevent_buf_size} \
-	$repoopts -a /tmp/apkovls
+	$repoopts -a "$ROOT"/tmp/apkovls
 eend $?
 
 # Setup network interfaces
@@ -633,8 +636,8 @@
 
 if [ -z "$KOPT_apkovl" ]; then
 	# Not manually set, use the apkovl found by nlplug
-	if [ -e /tmp/apkovls ]; then
-		ovl=$(head -n 1 /tmp/apkovls)
+	if [ -e "$ROOT"/tmp/apkovls ]; then
+		ovl=$(head -n 1 "$ROOT"/tmp/apkovls)
 	fi
 elif is_url "$KOPT_apkovl"; then
 	# Fetch apkovl via network
@@ -741,9 +744,9 @@
 	# move the ALPINE_MNT if ALPINE_DEV is specified in users fstab
 	# this is so a generated /etc/apk/repositories will use correct
 	# mount dir
-	relocate_mount "$sysroot"/etc/fstab
+	remount_fstab_entry "$sysroot"/etc/fstab
 elif [ -f "$ROOT"/etc/fstab ]; then
-	relocate_mount /etc/fstab
+	remount_fstab_entry "$ROOT"/etc/fstab
 fi
 
 # hack so we get openrc
@@ -829,20 +832,12 @@
 
 # remount according default fstab from package
 if [ -z "$has_fstab" ] && [ -f "$sysroot"/etc/fstab ]; then
-	relocate_mount "$sysroot"/etc/fstab
+	remount_fstab_entry "$sysroot"/etc/fstab
 fi
 
 # generate repositories if none exists. this needs to be done after relocation
 if ! [ -f "$sysroot"/etc/apk/repositories ]; then
 	find_boot_repositories > "$sysroot"/etc/apk/repositories
-fi
-
-# respect mount options in fstab for ALPINE_MNT (e.g if user wants rw)
-if [ -f "$sysroot"/etc/fstab ]; then
-	opts=$(awk "\$2 == \"$ALPINE_MNT\" {print \$4}" $sysroot/etc/fstab)
-	if [ -n "$opts" ]; then
-		$MOCK mount -o remount,$opts "$ALPINE_MNT"
-	fi
 fi
 
 # fix inittab if alternative console
--- a/tests/initramfs-init.test
+++ b/tests/initramfs-init.test
@@ -9,8 +9,10 @@
 	initramfs_init_tmpfs_root_modloop_sign \
 	initramfs_init_tmpfs_root_net_apkovl \
 	initramfs_init_tmpfs_root_console_serial \
-	initramfs_init_tmpfs_root_autodetect_serial
+	initramfs_init_tmpfs_root_autodetect_serial \
+	initramfs_init_tmpfs_root_remount_opts
 
+
 fake_cmdline() {
 	mkdir -p proc
 	echo "$@" > proc/cmdline
@@ -138,5 +140,48 @@
 	atf_check \
 		-o match:"ttyS0::respawn:/sbin/getty" \
 		cat sysroot/etc/inittab
+}
+
+initramfs_init_tmpfs_root_remount_opts_body() {
+	fake_cmdline ""
+	fake_switch_root
+	fake_sysroot_init
+	fake_bin df <<-EOF
+		#!/bin/sh
+		echo "Filesystem           1024-blocks    Used Available Capacity Mounted on"
+		echo "/dev/sr0    514938888 417682860  73101632  85% /media/sr0"
+	EOF
+	fake_bin stat <<-EOF
+		#!/bin/sh
+		for i; do
+			case "\$i" in
+				/dev/sr0|/dev/cdrom)
+					echo "b,0"
+					exit 0
+					;;
+			esac
+		done
+		echo "0,0"
+	EOF
+
+	mkdir -p sysroot/etc
+	cat >sysroot/etc/fstab <<-EOF
+		/dev/cdrom	/media/cdrom	iso9660	noauto,ro,customopts 0 0
+		/dev/usbdisk	/media/usb	vfat	noauto,ro 0 0
+	EOF
+	cat >proc/mounts <<-EOF
+		sysfs /sys sysfs rw,nosuid,nodev,noexec,relatime 0 0
+		devtmpfs /dev devtmpfs rw,nosuid,noexec,relatime,size=10240k,nr_inodes=4080869,mode=755,inode64 0 0
+		proc /proc proc rw,nosuid,nodev,noexec,relatime 0 0
+		/dev/sr0 /media/sr0 iso9660 rw,noatime,data=ordered 0 0
+	EOF
+	mkdir -p tmp dev media/sr0/apks
+	echo "/media/sr0/apks" > tmp/repositories
+	ln -s sr0 dev/cdrom
+
+	atf_check \
+		-o match:"mount -o move.*/media/cdrom" \
+		-o match:"mount -o remount.*customopts.*/media/cdrom" \
+		initramfs-init
 }