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

Bug#724931: Please include the patch in git



Control: affects -1 + hw-detect mountmedia

Hi,

the patch for this bug affects the following packages:
 * apt-setup
 * cdrom-detect
 * hw-detect (check-missing-firmware)
 * mountmedia
Since among the maintainers of all these packages is Christian Perrier, I'm sending this to you.

A short summary:
The patch created by Ian Bruce and myself adds ISO loopback support for the Debian installer using a new boot parameter, to be used as follows:

loopmount=[DEVICE:]ISO

Here ISO specifies the path to the ISO, i.e. /ISO/debian-7.1.0-amd64-CD-1.iso. DEVICE is for the name or UUID of the device, on which the ISO is located. Giving this is optional and if it is not given, all devices are searched for the ISO. If the boot parameter is not given (or no ISO could be found), everything works essentially as before.

For the patch to work, the loop-module is needed in the initrd, so I suggest to make it a dependency of cdrom-detect. I furthermore highly recommend to make the ext2/ext3/ext4, ntfs and udf modules dependencies of cdrom-detect, since these are the most common filesystems and thus being able to loopmount from them would be good. (Fat is somewhat outdated.) The patch makes it possible to boot using USB-HDD from any filesystems with drivers in the initrd.

The patch also cleans up the somewhat messy workaround for bug #608201.

For ease of use, I propose to add a loopback.cfg similar to the the attached one to the ISO in the folder /boot/grub/. This would allow to easily mount the ISO using grub2.


I tested loopmounting with the following ISOs. (They were modified with the attached Apply_Patches.sh.)
 * debian-7.1.0-amd64-netinst.iso
 * debian-7.1.0-i386-netinst.iso
 * debian-7.1.0-amd64-CD-1.iso
 * debian-7.1.0-amd64-CD-2.iso (+)
 * debian-7.1.0-amd64-CD-3.iso (+)
 * debian-7.1.0-amd64-DVD-1.iso
 * debian-7.1.0-amd64-DVD-2.iso (+)
(+): Not modified, just copied to the folder of the first ISO in the set.
This worked without problems. To make sure all other boot mechanisms still work, I tested them for the patched debian-7.1.0-amd64-CD-1.iso:
 * Isohybrid: OK
 * USB-HDD: OK
* CD: I can't open the CD drive with the button the on the drive. I have to change to another TTY and use 'eject'. (This problem exists also with the original ISO image, see #726137.)

Since the patch works well and does no harm, I ask you to include it in git.

Changes since the last patch:
* finish.d/10apt-cdrom-setup: Remove the whole 'deb file:' line. With the last patch, an empty line remained. * The script mountmedia uses 'mount -tauto', but this only tries to mount as fat and nothing else, so I changed this to detect the filesystem with blkid. Now firmware can be loaded from a harddrive/USB with any of the filesystems, for which drivers are in the initrd. * Removed $FATFS from cdrom-detect and instead let the filesystem be automatically detected using blkid. With this it is possible to use USB-HDD for all filesystems, for which drivers are in the initrd.
 * Removed iso-hybrid and usb-hdd templates, since it works well without.

Best regards,
Andreas

Attachment: Apply-Patches.sh
Description: application/shellscript

diff -rupN apt-cdrom-setup.orig/usr/bin/load-install-cd apt-cdrom-setup/usr/bin/load-install-cd
--- apt-cdrom-setup.orig/usr/bin/load-install-cd	2011-03-23 03:00:10.000000000 +0100
+++ apt-cdrom-setup/usr/bin/load-install-cd	2013-10-11 21:36:49.735038936 +0200
@@ -10,6 +10,13 @@ ROOT="$1"
 
 logoutput="log-output -t load-install-cd"
 
+# Why isn't this function, or something like it,
+# in /usr/share/debconf/confmodule ?
+db_getval()
+{
+	db_get "$1" && echo "$RET" || true
+}
+
 check_id() {
 	cd_ids=$(LC_ALL=C $logoutput --pass-stdout chroot $ROOT \
 		 apt-cdrom ident | grep "^Identifying" | cut -d" " -f2)
@@ -29,18 +36,9 @@ while ! check_id; do
 	db_go || exit 10
 done
 
-fs=iso9660
-if db_get cdrom-detect/cdrom_fs && [ "$RET" ]; then
-	fs="$RET"
-fi
-OS=$(udpkg --print-os)
-case "$OS" in
-	hurd)
-		OPTIONS=ro
-		;;
-	*)
-		OPTIONS=ro,exec
-		;;
-esac
+fs=$(db_getval cdrom-detect/cdrom_fs)
+[ "$fs" ] || fs=iso9660
+OPTIONS=$(db_getval cdrom-detect/cdrom_options)
+[ "$OPTIONS" ] || OPTIONS=ro,exec
 db_get cdrom-detect/cdrom_device
 $logoutput mount -t "$fs" -o $OPTIONS $RET /cdrom
diff -rupN apt-cdrom-setup.orig/usr/lib/apt-setup/generators/40cdrom apt-cdrom-setup/usr/lib/apt-setup/generators/40cdrom
--- apt-cdrom-setup.orig/usr/lib/apt-setup/generators/40cdrom	2013-05-12 12:49:10.000000000 +0200
+++ apt-cdrom-setup/usr/lib/apt-setup/generators/40cdrom	2013-10-11 00:19:52.494473022 +0200
@@ -10,7 +10,9 @@ if ! type chroot_cleanup_localmounts >/d
 	# Variant of chroot_cleanup that only cleans up chroot_setup's mounts.
 	chroot_cleanup_localmounts () {
 		rm -f /target/usr/sbin/policy-rc.d
-		mv /target/sbin/start-stop-daemon.REAL /target/sbin/start-stop-daemon
+		if [ -f /target/sbin/start-stop-daemon.REAL ]; then
+			mv /target/sbin/start-stop-daemon.REAL /target/sbin/start-stop-daemon
+		fi
 		if [ -x /target/sbin/initctl.REAL ]; then
 			mv /target/sbin/initctl.REAL /target/sbin/initctl
 		fi
@@ -40,32 +42,23 @@ if [ ! -s /cdrom/.disk/info ]; then
 	exit 0
 fi
 
-cd_mountable=1
-db_get cdrom-detect/hybrid || true
-if [ "$RET" = true ] || [ -d /hd-media ]; then
-	cd_mountable=""
-else
-	db_get cdrom-detect/usb-hdd || true
-	if [ "$RET" = true ]; then
-		cd_mountable=""
-	fi
-fi
+# Why isn't this function, or something like it,
+# in /usr/share/debconf/confmodule ?
+db_getval()
+{
+	db_get "$1" && echo "$RET" || true
+}
+
+# See whether the device is mountable
+cd_mountable=true
+cd_mountable=$(db_getval cdrom-detect/cdrom_mountable)
 
 remount_cd() {
-	if [ "$ROOT" ] && [ "$cd_mountable" ]; then
-		fs=iso9660
-		if db_get cdrom-detect/cdrom_fs && [ "$RET" ]; then
-			fs="$RET"
-		fi
-		OS=$(udpkg --print-os)
-		case "$OS" in
-			hurd)
-				OPTIONS=ro
-				;;
-			*)
-				OPTIONS=ro,exec
-				;;
-		esac
+	if [ "$ROOT" ] && [ $cd_mountable = true ]; then
+		fs=$(db_getval cdrom-detect/cdrom_fs)
+		[ "$fs" ] || fs=iso9660
+		OPTIONS=$(db_getval cdrom-detect/cdrom_options)
+		[ "$OPTIONS" ] || OPTIONS=ro,exec
 		db_get cdrom-detect/cdrom_device
 		$logoutput mount -t "$fs" -o $OPTIONS $RET /cdrom || true
 	fi
@@ -106,7 +99,7 @@ if [ "$ROOT" ]; then
 	chroot=chroot
 
 	# Allow apt-cdrom to manage mounting/unmounting CDs in /target
-	if [ "$cd_mountable" ]; then
+	if [ $cd_mountable = true ]; then
 		rm -f $ROOT/etc/apt/apt.conf.d/00NoMountCDROM
 
 		$logoutput umount /target/media/cdrom* || true
@@ -121,13 +114,17 @@ fi
 
 tmp=$($chroot $ROOT tempfile)
 
+# See whether /cdrom is a loopmounted ISO
+loopdev=$(db_getval cdrom-detect/cdrom_loopdev)
+
 # apt-cdrom can be interactive, avoid that
 if $logoutput $chroot $ROOT apt-cdrom add \
    -o Dir::Etc::SourceList=$tmp \
    </dev/null; then
 	cat $ROOT$tmp >> $file
 
-	if [ "$ROOT" ] && [ "$cd_mountable" ]; then
+	# Save the name of the CD to let the CD-set detection (among others) know, what the original CD was.
+	if [ "$ROOT" ] && ([ $cd_mountable = true ] || [ "$loopdev" ]); then
 		save_label
 	fi
 else
diff -rupN apt-cdrom-setup.orig/usr/lib/apt-setup/generators/41cdset apt-cdrom-setup/usr/lib/apt-setup/generators/41cdset
--- apt-cdrom-setup.orig/usr/lib/apt-setup/generators/41cdset	2011-01-19 05:26:34.000000000 +0100
+++ apt-cdrom-setup/usr/lib/apt-setup/generators/41cdset	2013-10-11 21:04:52.099123305 +0200
@@ -4,17 +4,22 @@ set -e
 . /usr/share/debconf/confmodule
 . /lib/chroot-setup.sh
 
+log() {
+	logger -t apt-setup "$@"
+}
+
 # This code is copied from chroot-setup.sh, and is needed until after a d-i
 # release whose initrds contain a sufficiently new version of di-utils.
 if ! type chroot_cleanup_localmounts >/dev/null 2>&1; then
 	# Variant of chroot_cleanup that only cleans up chroot_setup's mounts.
 	chroot_cleanup_localmounts () {
 		rm -f /target/usr/sbin/policy-rc.d
-		mv /target/sbin/start-stop-daemon.REAL /target/sbin/start-stop-daemon
+		if [ -f /target/sbin/start-stop-daemon.REAL ]; then
+			mv /target/sbin/start-stop-daemon.REAL /target/sbin/start-stop-daemon
+		fi
 		if [ -x /target/sbin/initctl.REAL ]; then
 			mv /target/sbin/initctl.REAL /target/sbin/initctl
 		fi
-
 		# Undo the mounts done by the packages during installation.
 		# Reverse sorting to umount the deepest mount points first.
 		# Items with count of 1 are new.
@@ -40,10 +45,13 @@ fi
 # KDE/Xfce CDs and multi-arch DVDs have '/single' postfix in cd_type
 # bluray CDs have cd_type 'bluray'
 cd_type=$(cat /cdrom/.disk/cd_type)
+log "The disk type is: $cd_type"
 if [ "$cd_type" != full_cd ] && [ "$cd_type" != dvd ]; then
 	exit 0
 fi
 
+log "Starting disk set detection"
+
 get_label() {
 	LC_ALL=C $logoutput --pass-stdout $chroot $ROOT \
 		apt-cdrom ident | grep "^Stored label:" | head -n1 | \
@@ -55,6 +63,17 @@ if [ "$CATCHLOG" ]; then
 	logoutput="log-output -t apt-setup"
 fi
 
+
+# Why isn't this function, or something like it,
+# in /usr/share/debconf/confmodule ?
+db_getval()
+{
+	db_get "$1" && echo "$RET" || true
+}
+
+# See whether /cdrom is a loopmounted ISO
+loopdev=$(db_getval cdrom-detect/cdrom_loopdev)
+
 chroot=
 if [ "$ROOT" ]; then
 	chroot=chroot
@@ -75,6 +94,19 @@ fi
 tmp=$($chroot $ROOT tempfile)
 
 cd_label=$(tail -n1 /var/lib/install-cd.id)
+
+if [ "$loopdev" ]; then
+	run_count=0
+	max_run=0
+	# Load the mount parameters for the CD
+	CDFS=$(db_getval cdrom-detect/cdrom_fs)
+	[ "$CDFS" ] || CDFS=iso9660
+	OPTIONS=$(db_getval cdrom-detect/cdrom_options)
+	[ "$OPTIONS" ] || OPTIONS=ro,exec
+fi
+
+log "First installation disk: $cd_label"
+
 db_subst apt-setup/cdrom/set-first LABEL "$cd_label"
 db_input high apt-setup/cdrom/set-first || true
 if ! db_go; then
@@ -86,7 +118,93 @@ fi
 db_get apt-setup/cdrom/set-first
 
 while [ "$RET" = true ]; do
-	cd_label=$(get_label)
+	cd_label=""
+	if [ "$loopdev" ]; then
+		if [ $run_count -eq 0 ]; then
+			log "Trying to find usable ISOs in the folder, where the boot ISO is..."
+			loopdir=$(db_getval cdrom-detect/cdrom_device)
+			ISOname=$(basename $loopdir)
+			loopdir=$(dirname $loopdir)
+			if [ "$cd_type" = "dvd" ]; then
+				# DVD
+				ISOstart=${filename%DVD-*}
+				ISOend=${filename#DVD-*}
+				ISOs=$(ls ${loopdir}/ | grep ${ISOstart}DVD-[^1].*[.]iso$)
+			elif [ "$cd_type" = "blueray" ]; then
+				# BD
+				ISOstart=${filename%BD-*}
+				ISOend=${filename#BD-*}
+				ISOs=$(ls ${loopdir}/ | grep ${ISOstart}BD-[^1].*[.]iso$)
+			else
+				# probably CD
+				ISOstart=${filename%CD-*}
+				ISOend=${filename#CD-*}
+				ISOs=$(ls ${loopdir}/ | grep ${ISOstart}CD-[^1].*[.]iso$)
+			fi
+			for iso in $ISOs; do
+				max_run=$(($max_run + 1))
+			done
+			log "Found $max_run ISO(s): $ISOs"
+		fi
+
+		try_iso=0
+		while [ $try_iso -eq 0 ]; do
+			if [ $run_count -lt $max_run ]; then
+				i=0
+				ISO=""
+				# select current ISO file
+				for isofile in $ISOs; do
+					if [ $i -eq $run_count ]; then
+						ISO=$isofile
+						break
+					fi
+					i=$(($i + 1))
+				done
+				j=1
+				# create mount point for the ISO
+				mount_point=/media/cdrom$j
+				while [ -d $ROOT$mount_point ]; do
+					j=$(($j + 1))
+					mount_point=/media/cdrom$j
+				done
+				mkdir $ROOT$mount_point
+
+				log "Try to loop mount file=$loopdir/$ISO, fstype=$CDFS to $ROOT$mount_point"
+				if mount -t $CDFS -o loop,$OPTIONS $loopdir/$ISO $ROOT$mount_point; then
+					log "CD-ROM mount succeeded: file=$loopdir/$ISO fstype=$CDFS"
+					if [ -e $ROOT$mount_point/.disk/info ]; then
+						CDNAME=$(cat $ROOT$mount_point/.disk/info | tr '"' '_')
+						log "Detected disk '$CDNAME'"
+						# Load the codename (e.g. jessie) from the database
+						db_get cdrom/codename
+						codename=$RET
+						RET=""
+						log "Detected codename: $codename"
+						try_iso=1
+					else
+						log "The disk in $loopdir/$ISO is not a Debian disk!"
+						umount $ROOT$mount_point 2>/dev/null || true
+						rmdir $ROOT$mount_point
+					fi
+				else
+					log "Mount failed: file=$loopdir/$ISO fstype=$CDFS"
+					umount $ROOT$mount_point 2>/dev/null || true
+					rmdir $ROOT$mount_point
+				fi
+			else
+				log "No more ISOs found"
+				break
+			fi
+			run_count=$(($run_count + 1))
+		done
+	fi
+
+	if [ "$loopdev" ] && [ $try_iso -eq 1 ]; then
+		cd_label=$CDNAME
+	else
+		cd_label=$(get_label)
+	fi
+
 	# Hmm. The greps could fail if a label contains regexp control chars...
 	if [ "$cd_label" ] && \
 	   (grep "^deb cdrom:\[$cd_label\]" $file || \
@@ -94,20 +212,36 @@ while [ "$RET" = true ]; do
 		template=apt-setup/cdrom/set-double
 		db_subst $template LABEL "$cd_label"
 	else
-		# apt-cdrom can be interactive, avoid that
-		if $logoutput $chroot $ROOT apt-cdrom add \
-		   -o Dir::Etc::SourceList=$tmp \
-		   </dev/null; then
-			cat $ROOT$tmp >> $file
+		if [ "$loopdev" ] && [ $try_iso -eq 1 ]; then
+			# Add an entry for the mount point of the ISO
+			printf "\ndeb [ trusted=yes ] file:$mount_point $codename main" >> $file
+			log "added log entry: 'deb [ trusted=yes ] file:$mount_point $codename main'"
+
+			# Make apt aware of the file
+			$logoutput $chroot $ROOT apt-cdrom -d $mount_point  add \
+			   -o Dir::Etc::SourceList=$tmp \
+			   </dev/null;
+
+			rm -f $ROOT$tmp $ROOT$tmp~
 
-			# Label is assigned by apt-cdrom add, so get again
-			cd_label=$(get_label)
 			template=apt-setup/cdrom/set-next
 			db_subst $template LABEL "$cd_label"
 		else
-			template=apt-setup/cdrom/set-failed
+			# apt-cdrom can be interactive, avoid that
+			if $logoutput $chroot $ROOT apt-cdrom add \
+			   -o Dir::Etc::SourceList=$tmp \
+			   </dev/null; then
+				cat $ROOT$tmp >> $file
+
+				# Label is assigned by apt-cdrom add, so get again
+				cd_label=$(get_label)
+				template=apt-setup/cdrom/set-next
+				db_subst $template LABEL "$cd_label"
+			else
+				template=apt-setup/cdrom/set-failed
+			fi
+			rm -f $ROOT$tmp $ROOT$tmp~
 		fi
-		rm -f $ROOT$tmp $ROOT$tmp~
 	fi
 
 	db_input critical $template || true
diff -rupN apt-cdrom-setup.orig/usr/lib/finish-install.d/10apt-cdrom-setup apt-cdrom-setup/usr/lib/finish-install.d/10apt-cdrom-setup
--- apt-cdrom-setup.orig/usr/lib/finish-install.d/10apt-cdrom-setup	2011-01-19 05:26:34.000000000 +0100
+++ apt-cdrom-setup/usr/lib/finish-install.d/10apt-cdrom-setup	2013-10-09 15:58:45.408856113 +0200
@@ -1,6 +1,29 @@
 #! /bin/sh
 set -e
 
+. /usr/share/debconf/confmodule
+
+# See whether /cdrom is a loopmounted ISO
+db_get cdrom-detect/cdrom_loopdev || true
+loopdev="$RET"
+
+if [ "$loopdev" ]; then
+	# Remove additional CD-Set mount points
+	j=1
+	while [ -d /target/media/cdrom/$j ]; do
+		logger -t finish-install "unmount /target/media/cdrom/$j"
+		umount /target/media/cdrom/$j 2>/dev/null || true
+		rmdir /target/media/cdrom/$j
+		j=$(($j + 1))
+	done
+
+	if grep -q "^deb[^:]* file:" /target/etc/apt/sources.list; then
+		logger -t finish-install "Removing additional ISOs from sources.list"
+		sed -i "/^deb[^:]* file:/d" /target/etc/apt/sources.list
+	fi
+	log-output -t finish-install chroot /target apt-get update
+fi
+
 # Disable netinst CD image in sources.list if any other sources are present
 if [ -e /cdrom/.disk/base_installable ] && \
    [ -e /cdrom/.disk/cd_type ] && \
diff -rupN debian-testing-amd64-netinst.orig/bin/check-missing-firmware debian-testing-amd64-netinst/bin/check-missing-firmware
--- debian-testing-amd64-netinst.orig/bin/check-missing-firmware	2013-08-16 15:10:00.000000000 +0200
+++ debian-testing-amd64-netinst/bin/check-missing-firmware	2013-10-07 17:42:12.120620713 +0200
@@ -246,6 +246,15 @@ check_for_firmware() {
 }
 
 while check_missing && ask_load_firmware; do
+	# If LOOPMOUNT is used, check the (busy) device from which the ISO is loaded
+	db_get cdrom-detect/cdrom_loopdev || true
+	if [ "$RET" ]; then
+		log "Check on /loop for firmware"
+		if [ -d /loop/firmware ]; then
+			check_for_firmware /loop/firmware/*.deb /loop/firmware/*.udeb
+		fi
+	fi
+
 	# first, check if needed firmware (u)debs are available on the
 	# PXE initrd or the installation CD.
 	if [ -d /firmware ]; then
diff -rupN debian-testing-amd64-netinst.orig/bin/mountmedia debian-testing-amd64-netinst/bin/mountmedia
--- debian-testing-amd64-netinst.orig/bin/mountmedia	2013-10-09 02:18:01.000000000 +0200
+++ debian-testing-amd64-netinst/bin/mountmedia	2013-10-09 23:54:17.899600786 +0200
@@ -27,13 +27,19 @@ media_mounted() {
 	mount | cut -d' ' -f3 | grep -q "^$MNT$"
 }
 
+get_fstype ()
+{
+	/sbin/blkid -s TYPE -o value $1 2>/dev/null
+}
+
 try_mount() {
 	# TO REMOVE, there is a bug somewhere in the kernel, the first
 	# mount command fail when changing floppy disk
 	# so we have to launch mount twice
-	mount $1 -tauto $MNT || true
+	fs_type=$(get_fstype $1)
+	mount -t $fs_type $1 $MNT || true
 	umount $MNT || true
-	mount $1 -tauto $MNT
+	mount -t $fs_type $1 $MNT
 	media_mounted && checkcontents $MNT
 }
 
diff -rupN debian-testing-amd64-netinst.orig/var/lib/dpkg/info/cdrom-detect.postinst debian-testing-amd64-netinst/var/lib/dpkg/info/cdrom-detect.postinst
--- debian-testing-amd64-netinst.orig/var/lib/dpkg/info/cdrom-detect.postinst	2013-08-17 11:10:50.000000000 +0200
+++ debian-testing-amd64-netinst/var/lib/dpkg/info/cdrom-detect.postinst	2013-10-11 00:12:46.942491745 +0200
@@ -1,4 +1,4 @@
-#! /bin/sh
+#!/bin/sh
 
 set -e
 . /usr/share/debconf/confmodule
@@ -14,26 +14,43 @@ fail() {
 	exit 1
 }
 
+list_devices_by_id()
+{
+	local dir disk="$(echo "$1" | sed 's/ /\\x20/g')"
+	for dir in /dev/disk/by-label /dev/disk/by-uuid ; do
+		[ -e ${dir}/${disk} ] && echo ${dir}/${disk} || true
+	done
+}
+
+get_fstype ()
+{
+	/sbin/blkid -s TYPE -o value $1 2>/dev/null
+}
+
 try_mount() {
 	local device=$1
 	local type=$2
+	local options=$3
+	local loopdev=$4
 
 	local ret=1
-	if mount -t $type -o $OPTIONS $device /cdrom; then
-		log "CD-ROM mount succeeded: device=$device fstype=$type"
+	if mount -o ${loopdev:+loop,}$options -t $type $device /cdrom; then
+		log "CD-ROM ${loopdev:+loop-}mount succeeded: device=$loopdev${device#/loop} fstype=$type"
 		if [ -e /cdrom/.disk/info ]; then
 			CDNAME=$(cat /cdrom/.disk/info)
 			log "Detected CD '$CDNAME'"
 			db_set cdrom-detect/cdrom_device $device
 			db_set cdrom-detect/cdrom_fs $type
+			db_set cdrom-detect/cdrom_options ${loopdev:+loop,}$options
+			db_set cdrom-detect/cdrom_loopdev $loopdev
 			ret=0
 		else
-			log "The CD in $device is not a Debian CD!"
+			log "The CD in $loopdev${device#/loop} is not a Debian CD!"
 			umount /cdrom 2>/dev/null || true
 			WRONG=1
 		fi
 	else
-		log "CD-ROM mount failed: device=$device fstype=$type"
+		log "CD-ROM ${loopdev:+loop-}mount failed: device=$loopdev${device#/loop} fstype=$type"
 	fi
 
 	return $ret
@@ -61,25 +78,21 @@ OS=$(udpkg --print-os)
 case "$OS" in
 	kfreebsd)
 		CDFS=cd9660
-		FATFS=msdosfs
 		OPTIONS=ro,exec
 		;;
 	linux)
 		CDFS=iso9660
-		FATFS=vfat
 		OPTIONS=ro,exec
 		;;
 	hurd)
 		CDFS=iso9660fs
-		FATFS=fatfs
 		OPTIONS=ro
 		;;
 	*)
 		log "Unknown OS '$OS', exiting"
 		exit 0
-		
 esac
- 
+
 # Is a cdrom already mounted? If so, assume it's the right one.
 mount | grep -q 'on /cdrom' && set_suite_and_codename && exit 0
 if [ -e /cdrom/.disk/info ]; then
@@ -95,42 +108,101 @@ log "Searching for Debian installation m
 
 mkdir /cdrom 2>/dev/null || true
 
+# Check whether the boot parameter 'loopmount=' is used
+for arg in $(cat /proc/cmdline); do
+	case $arg in
+	loopmount=*)
+		LOOPMOUNT=${arg#loopmount=}
+		LOOPFILE=${LOOPMOUNT#*:}
+		[ "$LOOPFILE" != "$LOOPMOUNT" ] && LOOPDEV=${LOOPMOUNT%:*}
+		;;
+	esac
+done
+
+if [ "$LOOPMOUNT" ]; then
+	# Create mount point for loop mount
+	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
-    devices="$(list-devices cd; list-devices maybe-usb-floppy)"
-    log "Devices: '$devices'"
-    if [ -n "$devices" ]; then
-      break 2
-    else
-      sleep 1
-    fi
-  done
+	for count in 1 2 3 4 5 6 8 9 10; do
+		devices="$(list-devices cd; list-devices maybe-usb-floppy)"
+		log "CD/maybe-usb-floppy devices: '$devices'"
+		if [ "$devices" ]; then
+			break
+		else
+			sleep 1
+		fi
+	done
 fi
 
+# This is for apt-cdrom-setup, that needs to know, whether or not it should try to automatically (u)mount the device.
+cd_mountable=true
+
 while true; do
-	WRONG=
+	WRONG=''
+
+	if [ "$LOOPMOUNT" ]; then
+		mounted=0
+		log "Searching for Debian ISO: LOOPDEV='$LOOPDEV' LOOPFILE='$LOOPFILE'"
+		loopfile=/loop/${LOOPFILE#/}
+		log "Unmounting /loop just to be sure"
+		umount /loop 2>/dev/null || true
+
+		if [ "$LOOPDEV" ] ; then
+			dev_given="device_given"
+		else
+			dev_given=""
+		fi
+
+		# First look for the given device (if given) and then on USB devices, since the ISO is probably on them
+		for fs in $dev_given "usb-partition" "cd" "partition"; do
+			if [ "$fs" = "device_given" ]; then
+				devices="$(list_devices_by_id "$LOOPDEV")"
+			else
+				devices="$(list-devices $fs)"
+			fi
+			log "Trying loopmount ($fs) on '$devices' ..."
+			for loopdev in $devices; do
+				# Determine the filesystem of the device
+				LOOPFS=$(get_fstype "$loopdev")
+				# Mount the device and try to mount the ISO specified by 'loopmount='
+				log "Try to mount device=$loopdev fstype=$LOOPFS"
+				if mount -o $OPTIONS -t $LOOPFS $loopdev /loop; then
+					log "Try to loop mount file=$loopfile fstype=$CDFS"
+					if [ -f $loopfile ] && try_mount $loopfile $CDFS $OPTIONS $loopdev; then
+						mounted=1
+						cd_mountable=false
+						break 2
+					else
+						umount /loop
+					fi
+				fi
+			done
+		done
+		if [ $mounted -eq 1 ]; then
+			log "Succesfully mounted the ISO: no need to check further devices"
+			break
+		fi
+	fi
 
 	devices="$(list-devices cd; list-devices maybe-usb-floppy)"
 	for device in $devices; do
-		if try_mount $device $CDFS; then
+		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; then
-			db_set cdrom-detect/hybrid true
-			break 2
-		fi
-		if try_mount $device $FATFS; then
-			db_set cdrom-detect/usb-hdd true
+		filesystem=$(get_fstype $device)
+		if try_mount $device $filesystem $OPTIONS; then
+			cd_mountable=false
 			break 2
 		fi
 	done
 
-
 	if [ "$WRONG" ]; then
 		db_input critical cdrom-detect/wrong-cd || [ $? -eq 30 ]
 		db_go
@@ -138,7 +210,7 @@ while true; do
 	fi
 
 	# If a device was detected but the mount failed, ask for the CD.
-	if [ -n "$devices" ]; then
+	if [ "$devices" ]; then
 		db_input critical cdrom-detect/retry || [ $? -eq 30 ]
 		db_go
 		db_get cdrom-detect/retry
@@ -150,7 +222,7 @@ while true; do
 			fail
 		fi
 	fi
- 
+
 	# If no device was detected, perhaps a driver floppy is needed.
 	if [ -e /usr/lib/debian-installer/retriever/media-retriever ]; then
 		db_input critical cdrom-detect/load_media
@@ -162,7 +234,7 @@ while true; do
 			continue
 		fi
 	fi
-    
+
 	# Otherwise manual configuration may be needed
 	db_input critical cdrom-detect/manual_config || [ $? -eq 30 ]
 	db_go
@@ -266,4 +338,12 @@ else
 	anna-install $RET-support || true
 fi
 
+# Check for hd-media folder, which implies that it is not booted from CD.
+if [ -d /hd-media ]; then
+	cd_mountable=false
+fi
+
+# This is for apt-cdrom-setup, that needs to know, whether or not it should try to automatically (u)mount the device.
+db_set cdrom-detect/cdrom_mountable $cd_mountable
+
 exit 0
diff -rupN debian-testing-amd64-netinst.orig/var/lib/dpkg/info/cdrom-detect.templates debian-testing-amd64-netinst/var/lib/dpkg/info/cdrom-detect.templates
--- debian-testing-amd64-netinst.orig/var/lib/dpkg/info/cdrom-detect.templates	2013-10-07 02:06:30.000000000 +0200
+++ debian-testing-amd64-netinst/var/lib/dpkg/info/cdrom-detect.templates	2013-10-11 00:15:05.562485646 +0200
@@ -1097,17 +1097,22 @@ Default: iso9660
 Description: for internal use only
  File system used on cdrom-detect/cdrom_device.
 
-Template: cdrom-detect/hybrid
-Type: boolean
-Default: false
+Template: cdrom-detect/cdrom_options
+Type: string
+Default: ro,exec
 Description: for internal use only
- Set if the CD appears to be on a USB stick.
+ Options used to mount the cdrom-detect/cdrom_device.
 
-Template: cdrom-detect/usb-hdd
-Type: boolean
-Default: false
+Template: cdrom-detect/cdrom_loopdev
+Type: string
 Description: for internal use only
- Set if the CD appears to be a live USB-HDD image.
+ Set if a ISO is loopmounted.
+
+Template: cdrom-detect/cdrom_mountable
+Type: boot
+Default: true
+Description: for internal use (communication with apt-cdrom-setup) only
+ This should be false, if the mounted device is not a removable disk in a drive.
 
 Template: cdrom-detect/scanning_progress_title
 Type: text
menuentry 'Install' {
	set gfxpayload=auto
	linux	/install.amd/vmlinuz loopmount=$iso_path quiet $boot_options
	initrd	/install.amd/initrd.gz
}
menuentry 'Graphical install' {
	set gfxpayload=auto
	linux	/install.amd/vmlinuz loopmount=$iso_path quiet $boot_options
	initrd	/install.amd/gtk/initrd.gz
}
submenu 'Advanced options ...' {
	menuentry '... Expert install' {
		set gfxpayload=auto
		linux	/install.amd/vmlinuz priority=low loopmount=$iso_path $boot_options
		initrd	/install.amd/initrd.gz
	}
	menuentry '... Rescue mode' {
		set gfxpayload=auto
		linux	/install.amd/vmlinuz rescue/enable=true loopmount=$iso_path quiet $boot_options
		initrd	/install.amd/initrd.gz
	}
	menuentry '... Automated install' {
		set gfxpayload=auto
		linux	/install.amd/vmlinuz auto=true priority=critical loopmount=$iso_path quiet $boot_options
		initrd	/install.amd/initrd.gz
	}
	menuentry '... Graphical expert install' {
		set gfxpayload=auto
		linux	/install.amd/vmlinuz priority=low loopmount=$iso_path $boot_options
		initrd	/install.amd/gtk/initrd.gz
	}
	menuentry '... Graphical rescue mode' {
		set gfxpayload=auto
		linux	/install.amd/vmlinuz rescue/enable=true loopmount=$iso_path quiet $boot_options 
		initrd	/install.amd/gtk/initrd.gz
	}
	menuentry '... Graphical automated install' {
		set gfxpayload=auto
		linux	/install.amd/vmlinuz auto=true priority=critical loopmount=$iso_path quiet $boot_options
		initrd	/install.amd/gtk/initrd.gz
	}
	submenu '... Desktop environment menu ...' {
		submenu '... KDE desktop boot menu ...' {
			menuentry '... Install' {
				set gfxpayload=auto
				linux	/install.amd/vmlinuz desktop=kde loopmount=$iso_path quiet $boot_options
				initrd	/install.amd/initrd.gz
			}
			menuentry '... Graphical install' {
				set gfxpayload=auto
				linux	/install.amd/vmlinuz desktop=kde loopmount=$iso_path quiet $boot_options
				initrd	/install.amd/gtk/initrd.gz
			}
			submenu '... KDE advanced options ...' {
				menuentry '... Expert install' {
					set gfxpayload=auto
					linux	/install.amd/vmlinuz desktop=kde priority=low loopmount=$iso_path $boot_options
					initrd	/install.amd/initrd.gz
				}
				menuentry '... Automated install' {
					set gfxpayload=auto
					linux	/install.amd/vmlinuz desktop=kde auto=true priority=critical loopmount=$iso_path quiet $boot_options
					initrd	/install.amd/initrd.gz
				}
				menuentry '... Graphical expert install' {
					set gfxpayload=auto
					linux	/install.amd/vmlinuz desktop=kde priority=low video=vesa:ywrap,mtrr loopmount=$iso_path $boot_options
					initrd	/install.amd/gtk/initrd.gz
				}
				menuentry '... Graphical automated install' {
					set gfxpayload=auto
					linux	/install.amd/vmlinuz desktop=kde auto=true priority=critical loopmount=$iso_path quiet $boot_options
					initrd	/install.amd/gtk/initrd.gz
				}
			}
		}
		submenu '... LXDE desktop boot menu ...' {
			menuentry '... Install' {
					set gfxpayload=auto
				linux	/install.amd/vmlinuz desktop=lxde loopmount=$iso_path quiet $boot_options
				initrd	/install.amd/initrd.gz
			}
			menuentry '... Graphical install' {
					set gfxpayload=auto
				linux	/install.amd/vmlinuz desktop=lxde loopmount=$iso_path quiet $boot_options
				initrd	/install.amd/gtk/initrd.gz
			}
			submenu '... LXDE advanced options ...' {
				menuentry '... Expert install' {
					set gfxpayload=auto
					linux	/install.amd/vmlinuz desktop=lxde priority=low loopmount=$iso_path $boot_options
					initrd	/install.amd/initrd.gz
				}
				menuentry '... Automated install' {
					set gfxpayload=auto
					linux	/install.amd/vmlinuz desktop=lxde auto=true priority=critical loopmount=$iso_path quiet $boot_options
					initrd	/install.amd/initrd.gz
				}
				menuentry '... Graphical expert install' {
					set gfxpayload=auto
					linux	/install.amd/vmlinuz desktop=lxde priority=low loopmount=$iso_path $boot_options
					initrd	/install.amd/gtk/initrd.gz
				}
				menuentry '... Graphical automated install' {
					set gfxpayload=auto
					linux	/install.amd/vmlinuz desktop=lxde auto=true priority=critical loopmount=$iso_path quiet $boot_options
					initrd	/install.amd/gtk/initrd.gz
				}
			}
		}
		submenu '... Xfce desktop boot menu ...' {
			menuentry '... Install' {
					set gfxpayload=auto
				linux	/install.amd/vmlinuz desktop=xfce loopmount=$iso_path quiet $boot_options
				initrd	/install.amd/initrd.gz
			}
			menuentry '... Graphical install' {
					set gfxpayload=auto
				linux	/install.amd/vmlinuz desktop=xfce loopmount=$iso_path quiet $boot_options
				initrd	/install.amd/gtk/initrd.gz
			}
			submenu '... Xfce advanced options ...' {
				menuentry '... Expert install' {
					set gfxpayload=auto
					linux	/install.amd/vmlinuz desktop=xfce priority=low loopmount=$iso_path $boot_options
					initrd	/install.amd/initrd.gz
				}
				menuentry '... Automated install' {
					set gfxpayload=auto
					linux	/install.amd/vmlinuz desktop=xfce auto=true priority=critical loopmount=$iso_path quiet $boot_options
					initrd	/install.amd/initrd.gz
				}
				menuentry '... Graphical expert install' {
					set gfxpayload=auto
					linux	/install.amd/vmlinuz desktop=xfce priority=low loopmount=$iso_path $boot_options
					initrd	/install.amd/gtk/initrd.gz
				}
				menuentry '... Graphical automated install' {
					set background_color=black
					linux	/install.amd/vmlinuz desktop=xfce auto=true priority=critical loopmount=$iso_path quiet $boot_options
					initrd	/install.amd/gtk/initrd.gz
				}
			}
		}
	}
}
menuentry 'Install with speech synthesis' {
	set gfxpayload=auto
	linux	/install.amd/vmlinuz speakup.synth=soft loopmount=$iso_path quiet $boot_options
	initrd	/install.amd/gtk/initrd.gz
}

Reply to: