[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

PATCH: specify pathname for ISO loop-mount



This patch introduces a boot parameter, "loopmount=", which allows the
specification of a full pathname (relative to the root directory of some
block device) of an ISO image file which should be loop-mounted as the
Debian installer root filesystem.

The main purpose of this feature is to facilitate the creation of USB
flashdrives which can contain multiple Linux live distributions,
selectable at boot time via a Syslinux menu.

http://sourceforge.net/projects/multibootusb/

The current method of creating a Debian installer flashdrive overwrites
the existing partition table and filesystem:

    *Warning*

    The procedures described in this section will destroy anything
    already on the device!

http://www.debian.org/releases/stable/amd64/ch04s03.html.en

This is unnecessarily destructive, and makes it hard to install multiple
distributions on the same flashdrive, or to use it for other purposes.
The smallest flashdrive you can currently buy is 8GB; it makes no sense
that you would have to have a different one for every live ISO you might
want to use.

The effect of this patch is that you can just copy the Debian installer
ISO into the existing filesystem on the flashdrive, and boot it with
GRUB or Syslinux, using the "loopmount=" boot parameter to specify the
ISO pathname.

It will be apparent from reading the patch that if this parameter is not
specified, everything functions EXACTLY as before; the new code will not
be run. The changes amount to no more than forty lines of new code, in
one file.

I suppose that this patch applies to the "cdrom-detect" udeb, although I
just patched the initrd directly. A dependency on "loop-modules" will
need to be added, to make sure that the "loop.ko" kernel module gets
copied into the initrd.

One issue that probably should be addressed is what to do if the
specified ISO is not actually present; the boot process should fail
gracefully, but I'm not sure how best to accomplish that.

Minor changes (see the "LOOPFS" variable) would be needed to make it
work for FreeBSD and Hurd; I've only tried it with Linux.

Comments are welcome, but apart from the above, I don't think there's
much wrong with this patch; testing shows that it seems to work
perfectly.


-- Ian Bruce
--- debian-7.1.0-amd64.orig/var/lib/dpkg/info/cdrom-detect.postinst	2013-09-10 17:45:08.305375296 -0700
+++ debian-7.1.0-amd64/var/lib/dpkg/info/cdrom-detect.postinst	2013-09-28 00:14:38.058505180 -0700
@@ -17,9 +17,10 @@
 try_mount() {
 	local device=$1
 	local type=$2
+	local options=$3
 
 	local ret=1
-	if mount -t $type -o $OPTIONS $device /cdrom; then
+	if mount -t $type -o $options $device /cdrom; then
 		log "CD-ROM mount succeeded: device=$device fstype=$type"
 		if [ -e /cdrom/.disk/info ]; then
 			CDNAME=$(cat /cdrom/.disk/info)
@@ -68,6 +69,7 @@
 		CDFS=iso9660
 		FATFS=vfat
 		OPTIONS=ro,exec
+		LOOPFS=vfat,ext4,iso9660
 		;;
 	hurd)
 		CDFS=iso9660fs
@@ -95,6 +97,19 @@
 
 mkdir /cdrom 2>/dev/null || true
 
+for arg in $(cat /proc/cmdline); do
+	case $arg in
+	loopmount=*)
+		LOOPMOUNT=${arg#loopmount=}
+		LOOPMOUNT=${LOOPMOUNT#/}
+		;;
+	esac
+done
+
+if [ "$LOOPMOUNT" ]; then
+	mkdir /loop 2>/dev/null || true
+fi
+
 # Need to wait for the usb device scan to complete
 if [ "$OS" = "linux" ]; then
   for count in 1 2 3 4 5 6 8 9 10; do
@@ -109,26 +124,45 @@
 fi
 
 while true; do
-	WRONG=
+	WRONG=''
 
-	devices="$(list-devices cd; list-devices maybe-usb-floppy)"
-	for device in $devices; do
-		if try_mount $device $CDFS; then
-			break 2
-		fi
-	done
-	
-	devices="$(list-devices usb-partition)"
-	for device in $devices; do
-		if try_mount $device $CDFS; then
-			db_set cdrom-detect/hybrid true
-			break 2
-		fi
-		if try_mount $device $FATFS; then
-			db_set cdrom-detect/usb-hdd true
-			break 2
-		fi
-	done
+	if [ "$LOOPMOUNT" ]
+	then
+
+		loopfile=/loop/${LOOPMOUNT}
+		devices="$(list-devices partition; list-devices cd)"
+		for device in $devices; do
+			if mount -o $OPTIONS -t $LOOPFS $device /loop; then
+				if [ -f $loopfile ] && try_mount $loopfile $CDFS loop,$OPTIONS; then
+					break 2
+				else
+					umount /loop
+				fi
+			fi
+		done
+
+	else
+
+		devices="$(list-devices cd; list-devices maybe-usb-floppy)"
+		for device in $devices; do
+			if try_mount $device $CDFS $OPTIONS; then
+				break 2
+			fi
+		done
+
+		devices="$(list-devices usb-partition)"
+		for device in $devices; do
+			if try_mount $device $CDFS $OPTIONS; then
+				db_set cdrom-detect/hybrid true
+				break 2
+			fi
+			if try_mount $device $FATFS $OPTIONS; then
+				db_set cdrom-detect/usb-hdd true
+				break 2
+			fi
+		done
+
+	fi
 
 
 	if [ "$WRONG" ]; then

Reply to: