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

Bug#724931: Patch for bugs #724931 and #724933



tags 724931 patch
tags 724933 patch
thanks

Hi,

I made some changes/improvements to the patch provided by Ian:
* Support a 'firmware' folder on the same device as the ISO: Due to being mounted, it was not automatically checked with the old patch. * Removed "DISTRIB_LABEL" variable: Such things should not be hard-coded! Furthermore, this is unrelated to the 'loopmount=' option (and I don't know what the benefit of this should be). Ian, if you want something like this you probably should open another bug and explain there the need for this further. * Added support for kfreebsd/hurd and any filesystem by using blkid to detect the filesystem of the device to be mounted. * Added iteration loop over $dev_given (i.e. is it used as 'loopmount=DEVICE:ISO'), "usb-partition", "cd" and "partition". This is to ensure, that the most likely sources are looked at first.
 * Changed/added log messages
 * Added comments
 * Corrected formatting and removed trailing whitespaces

The new apt-cdrom-setup patch enables the ISOs to be added to /etc/apt/sources.list:
 * Don't (u)mount for ISOs
* Added a if-clause to the chroot_cleanup_localmounts hack, to prevent it from moving a file, that is possibly not even there (especially since it get's removed in 40cdrom and 41cdset). * Added cd-set support: ISOs from the set (i.e. starting with the same string up to 'CD-' (or 'DVD-' for DVDs resp. 'BD-' for bluerays)) in the same directory can be loaded. (The entries for the additional files are removed, when the installation is finished.)

I would also suggest to add a loopback.cfg (similar to the one I attached) to /boot/grub/. (By the way, I noticed that the /boot folder is missing from the debian-7.1.0-i386-netinst.iso. It should be added there.) If it is possible, this should also be done for /isolinux. Then it can be loaded by grub2 with e.g.:
menuentry "Debian Testing Netinstall (64 bit)" {
	set gfxpayload=auto
	set iso_path="/ISO/debian-testing-amd64-netinst.iso"
	export iso_path
	boot_options=locale=de_DE.UTF-8
	loopback loop $iso_path
	set root=(loop)
	configfile /boot/grub/loopback.cfg
	loopback -d loop
}

I also updated the script to apply the patches for testing purposes:
 This script has to be executed with root privileges!
It's first argument is the path/filename of the Debian install ISO file to be patched. The filename should contain amd64 or i386, indicating which architecture is used.
 The ISO will be mounted to /mnt, which will be umounted before.
If a loopback.cfg is in the directory where the script is executed, it will be included in /boot/grub/. If the architecture is i386, every '.amd' in the loopback.cfg will be changed to '.386'. The script's second argument is the patch file to be applied to initrd (e.g. initrd_loopmount.patch). It's third argument is the patch file to be applied to the apt-cdrom-setup udeb (e.g. apt-cdrom-setup_loopmount.patch). It will create a patched ISO named ${ISO}-loopmount.iso in the directory where it is executed.

I tested with the following ISOs:
 * debian-testing-amd64-netinst-loopmount.iso
 * debian-7.1.0-i386-netinst-loopmount.iso
 * debian-7.1.0-amd64-netinst-loopmount.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-loopmount.iso
 * debian-7.1.0-amd64-DVD-2-loopmount.iso (+)
(+) These ISOs were not modified, but just copied to the same directory as the first ISO of the set on the USB stick.

Problems that I noticed with this patch:
* The CD-set installation (CD 1, 2 and 3) works well, until it actually tries to install the packages. Then tasksel fails, complaining about unauthenticated packages: For the installation to continue, one has to change the following line in /target/usr/bin/tasksel push @cmd, qw{apt-get -q -y -o APT::Install-Recommends=true -o APT::Get::AutomaticRemove=true install};
   to:
push @cmd, qw{apt-get -q -y --force-yes -o APT::Install-Recommends=true -o APT::Get::AutomaticRemove=true install}; This seems OK, since I changed a package in the original CD and thus the Release.gpg is not a good signature. But I did not change anything on CD-2 or CD-3 that I loaded. Therefore this error should also occur if only installing from the first CD, but it does not: the installation works fine (though without print-server and laptop task)! I'm not sure what the correct behaviour should be, but this is clearly inconsistent: Either it should reject installation from the first CD, since that is the 'bad' one, or it should also allow installation with multiple CDs. Perhaps the later is the case, but I misconfigured the additional CDs? I had to use 'deb file:' for this, since when using 'deb cdrom:', the installer stops, when the next CD needs to be mounted, and I found no way to automate this. Apparently apt does not support the concept of multiple CD drives.

* When the installation (including gnome desktop) from the CD set (CDs 1, 2 and 3) or the DVD-1 is nearly finished, the error
   "Could not build the hash file for en-common"
occurs and it is suggested, that one sends a complaint to the maintainer of the package that provides 'en'.
   The error message in /var/log/syslog are the following two lines:
   aspell-autobuildhash: processing: en [en-common]
   Error: /dev/null:1: The key "/usr/bin/aspell" is unknown.
I think the error is unrelated to this patch, but I am not sure, since I cannot test it with the original ISO, because that doesn't support multiple CDs when booting from USB (and my spare USB for isohybrid testing is too small for the DVD).

On 04.10.2013 15:02, ian_bruce@fastmail.net wrote:
> The effect of my second patch is that the ISO no longer has to be
> "found"; we can specify EXACTLY where (what filesystem, what pathname)
> it is located, and so that parameter name is now even more
> inappropriate, and that implementation quite incompatible with mine.
I agree that now the functionality is (from the user's point of view) different to that in the live image, because of the possibility to specify the device by "loopmount=DEVICE:ISO". Using such a string with the findiso from the live image surely doesn't work. So I think the best is to use the name loopmount and when (if?) the new functionality is added to the live image, they should change their name accordingly.

>> and I am sure, that they would gladly add any additional features
>> implemented in the debian-installer.
>
> I'm not at all sure about that. I've previously found them to be quite
> unwilling to make obviously beneficial changes, without being able to
> provide any rational reason for that refusal.
>
> http://lists.debian.org/debian-live/2013/08/threads.html#00054
> http://lists.debian.org/debian-live/2013/09/threads.html#00000
I read the discussion and let me add my opinion: I think the Debian live team wants to avoid any additional work, which is quite understandable, since they probably have enough to do already (and do quite a good job). But in this special case I wonder, if it wouldn't have been less work just to include the two packages than to write all those mails...

> And notice that so far, loopmount ISN'T implemented in the Debian
> installer; this discussion doesn't yet involve anybody except you and
> me.
I think (and very much hope) that a number of people on the debian-boot mailing list also read this discussion and are therefore 'involved'. Before, the patch had problems, which are solved now. So I think this patch is ready for being included in all the Debian installers, since from the remaining two problems, that I could detect with this patch, one is probably solved by an official build (Release.gpg issue), and the other is apparently a bug in a different package (aspell).

When the patch is included, the documentation for installation from USB needs to be updated.

>> The iso-scan package on the other hand seems not be in use currently.
>
>It turns out that it is, but only in the "hd-media" images, not the
>standard ISOs.
Oh, I forgot the hd-media images, because ... ugh ... well ... they are not included on any Debian installation ISO! ;)

> (I don't patch ISOs, but only initrds, because I prefer that the
> official MD5 and SHA256 hashes can still be verified.)
I also prefer the official signed hashes, but this script is meant for testing purposes only, and will be obsolete, as soon as this patch is included in the Debian installer.

> You said it had to be
> executed with root privileges, presumably so that file ownership and
> device files come out right. You should investigate the "fakeroot"
> utility, which obviates the need for this.
The script attached to this mail needs root privileges to (u)mount the ISO, so it wouldn't make much difference, if I used fakeroot for the rest.

> And is it possible to rename the bug report to something more
> descriptive?
Feel free to rename it to whatever you think is best by sending a mail with the following content ('NEW_TITLE' appropriately replaced) to control@bugs.debian.org:
retitle 724931 NEW_TITLE
thanks

I hope the loopmount option will soon be in the official Debian installation ISOs.

Best regards,
Andreas

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

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-05 20:16:34.143372897 +0200
@@ -246,6 +246,24 @@ check_for_firmware() {
 }
 
 while check_missing && ask_load_firmware; do
+	# 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 is used, check the (busy) device from which the ISO is loaded
+	if [ "$LOOPMOUNT" ]; 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/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-05 23:53:30.266800234 +0200
@@ -14,12 +14,26 @@ 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 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)
@@ -77,9 +91,8 @@ case "$OS" in
 	*)
 		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,41 +108,103 @@ 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 "Devices: '$devices'"
+		if [ "$devices" ]; then
+			break 2
+		else
+			sleep 1
+		fi
+	done
 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
+	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
-		if try_mount $device $FATFS; then
-			db_set cdrom-detect/usb-hdd true
-			break 2
+		
+		# First look for 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 device in $devices; do
+				# Determine the filesystem of the device
+				LOOPFS=$(get_fstype "${device}")
+				# Mount the device and try to mount the ISO specified by 'loopmount='
+				log "Try to mount device=$device fstype=$LOOPFS"
+				if mount -o $OPTIONS -t $LOOPFS $device /loop; then
+					log "Try to loop mount file=$loopfile fstype=$CDFS"
+					if [ -f $loopfile ] && try_mount $loopfile $CDFS loop,$OPTIONS; then
+						log "ISO succesfully mounted"
+						mounted=1
+						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
-	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
 		db_input critical cdrom-detect/wrong-cd || [ $? -eq 30 ]
@@ -138,7 +213,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 +225,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 +237,7 @@ while true; do
 			continue
 		fi
 	fi
-    
+
 	# Otherwise manual configuration may be needed
 	db_input critical cdrom-detect/manual_config || [ $? -eq 30 ]
 	db_go
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-05 20:17:10.000000000 +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
@@ -51,6 +53,23 @@ else
 	fi
 fi
 
+# 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
+
+# ISOs are used, don't try to (u)mount anything
+if [ "$LOOPMOUNT" ]; then
+	logger -t apt-setup "Booted from ISO; Don't allow apt-cdrom to manage mounting/unmounting CDs in /target"
+	cd_mountable=""
+fi
+
 remount_cd() {
 	if [ "$ROOT" ] && [ "$cd_mountable" ]; then
 		fs=iso9660
@@ -130,6 +149,9 @@ if $logoutput $chroot $ROOT apt-cdrom ad
 	if [ "$ROOT" ] && [ "$cd_mountable" ]; then
 		save_label
 	fi
+	if [ "$ROOT" ] && [ "$LOOPMOUNT" ]; then
+		save_label
+	fi
 else
 	bail_out
 fi
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-06 02:57:30.000000000 +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,6 +45,7 @@ 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
@@ -55,6 +61,8 @@ if [ "$CATCHLOG" ]; then
 	logoutput="log-output -t apt-setup"
 fi
 
+log "Starting disk set detection"
+
 chroot=
 if [ "$ROOT" ]; then
 	chroot=chroot
@@ -72,21 +80,138 @@ if [ "$ROOT" ]; then
 	trap chroot_cleanup_localmounts EXIT HUP INT QUIT TERM
 fi
 
+# 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
+
 tmp=$($chroot $ROOT tempfile)
 
 cd_label=$(tail -n1 /var/lib/install-cd.id)
+
+if [ "$LOOPMOUNT" ]; then
+	run_count=0
+	max_run=0
+	CDFS=iso9660
+	if db_get cdrom-detect/cdrom_fs && [ "$RET" ]; then
+		CDFS="$RET"
+	fi
+	OS=$(udpkg --print-os)
+	case "$OS" in
+		hurd)
+			OPTIONS=ro
+			;;
+		*)
+			OPTIONS=ro,exec
+			;;
+	esac
+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
-	if [ "$ROOT" ]; then
+	if [ "$ROOT" ] && ! [ "$LOOPMOUNT" ]; then
 		load-install-cd "$ROOT"
 	fi
 	exit 10
 fi
 db_get apt-setup/cdrom/set-first
 
+log "Start detecting .."
+
 while [ "$RET" = true ]; do
-	cd_label=$(get_label)
+	cd_label=""
+	if [ "$LOOPMOUNT" ]; then
+		if [ $run_count -eq 0 ]; then
+			log "Trying to find usable ISOs in the folder, where the boot ISO is..."
+			loopdir=$(dirname /loop/${LOOPMOUNT})
+			ISOname=$(basename ${LOOPMOUNT})
+			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
+					fi
+				else
+					log "Mount failed: file=$loopdir/$ISO fstype=$CDFS"
+					umount $ROOT$mount_point 2>/dev/null || true
+				fi
+			else
+				log "No more ISOs found"
+				break
+			fi
+			run_count=$(($run_count + 1))
+		done
+	fi
+	
+	if [ "$LOOPMOUNT" ] && [ $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,25 +219,39 @@ 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 [ "$LOOPMOUNT" ] && [ $try_iso -eq 1 ]; then
+			# Add an entry for the mount point of the ISO
+			printf "\ndeb file:$mount_point $codename main" >> $file
+			log "added log entry: 'deb file:$mount_point $codename main'"
+
+			# Make apt aware of the file
+			$logoutput $chroot $ROOT apt-cdrom -d $mount_point  add \
+			   -o Dir::Etc::SourceList=/dev/null \
+			   </dev/null;
 
-			# 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
 	if ! db_go; then
-		if [ "$ROOT" ]; then
+		if [ "$ROOT" ] && ! [ "$LOOPMOUNT" ]; then
 			load-install-cd "$ROOT"
 		fi
 		exit 10
@@ -121,6 +260,6 @@ while [ "$RET" = true ]; do
 done
 
 # Make sure the installation CD is loaded again
-if [ "$ROOT" ]; then
+if [ "$ROOT" ] && ! [ "$LOOPMOUNT" ]; then
 	load-install-cd "$ROOT"
 fi
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-06 04:01:12.000000000 +0200
@@ -1,6 +1,34 @@
 #! /bin/sh
 set -e
 
+# 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
+	# 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 "s/^deb file:.*//g" /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 ] && \
menuentry 'Install' {
	set gfxpayload=auto
	linux	/install.amd/vmlinuz loopback=$iso_path $boot_options -- quiet 
	initrd	/install.amd/initrd.gz
}
menuentry 'Graphical install' {
	set gfxpayload=auto
	linux	/install.amd/vmlinuz loopback=$iso_path $boot_options -- quiet 
	initrd	/install.amd/gtk/initrd.gz
}
submenu 'Advanced options ...' {
	menuentry '... Expert install' {
		set gfxpayload=auto
		linux	/install.amd/vmlinuz priority=low loopback=$iso_path $boot_options -- 
		initrd	/install.amd/initrd.gz
	}
	menuentry '... Rescue mode' {
		set gfxpayload=auto
		linux	/install.amd/vmlinuz rescue/enable=true loopback=$iso_path $boot_options -- quiet 
		initrd	/install.amd/initrd.gz
	}
	menuentry '... Automated install' {
		set gfxpayload=auto
		linux	/install.amd/vmlinuz auto=true priority=critical loopback=$iso_path $boot_options -- quiet 
		initrd	/install.amd/initrd.gz
	}
	menuentry '... Graphical expert install' {
		set gfxpayload=auto
		linux	/install.amd/vmlinuz priority=low loopback=$iso_path $boot_options -- 
		initrd	/install.amd/gtk/initrd.gz
	}
	menuentry '... Graphical rescue mode' {
		set gfxpayload=auto
		linux	/install.amd/vmlinuz rescue/enable=true loopback=$iso_path $boot_options -- quiet  
		initrd	/install.amd/gtk/initrd.gz
	}
	menuentry '... Graphical automated install' {
		set gfxpayload=auto
		linux	/install.amd/vmlinuz auto=true priority=critical loopback=$iso_path $boot_options -- quiet 
		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 loopback=$iso_path $boot_options -- quiet 
				initrd	/install.amd/initrd.gz
			}
			menuentry '... Graphical install' {
				set gfxpayload=auto
				linux	/install.amd/vmlinuz desktop=kde loopback=$iso_path $boot_options -- quiet 
				initrd	/install.amd/gtk/initrd.gz
			}
			submenu '... KDE advanced options ...' {
				menuentry '... Expert install' {
					set gfxpayload=auto
					linux	/install.amd/vmlinuz desktop=kde priority=low loopback=$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 loopback=$iso_path $boot_options -- quiet 
					initrd	/install.amd/initrd.gz
				}
				menuentry '... Graphical expert install' {
					set gfxpayload=auto
					linux	/install.amd/vmlinuz desktop=kde priority=low video=vesa:ywrap,mtrr loopback=$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 loopback=$iso_path $boot_options -- quiet 
					initrd	/install.amd/gtk/initrd.gz
				}
			}
		}
		submenu '... LXDE desktop boot menu ...' {
			menuentry '... Install' {
					set gfxpayload=auto
				linux	/install.amd/vmlinuz desktop=lxde loopback=$iso_path $boot_options -- quiet 
				initrd	/install.amd/initrd.gz
			}
			menuentry '... Graphical install' {
					set gfxpayload=auto
				linux	/install.amd/vmlinuz desktop=lxde loopback=$iso_path $boot_options -- quiet 
				initrd	/install.amd/gtk/initrd.gz
			}
			submenu '... LXDE advanced options ...' {
				menuentry '... Expert install' {
					set gfxpayload=auto
					linux	/install.amd/vmlinuz desktop=lxde priority=low loopback=$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 loopback=$iso_path $boot_options -- quiet 
					initrd	/install.amd/initrd.gz
				}
				menuentry '... Graphical expert install' {
					set gfxpayload=auto
					linux	/install.amd/vmlinuz desktop=lxde priority=low loopback=$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 loopback=$iso_path $boot_options -- quiet 
					initrd	/install.amd/gtk/initrd.gz
				}
			}
		}
		submenu '... Xfce desktop boot menu ...' {
			menuentry '... Install' {
					set gfxpayload=auto
				linux	/install.amd/vmlinuz desktop=xfce loopback=$iso_path $boot_options -- quiet 
				initrd	/install.amd/initrd.gz
			}
			menuentry '... Graphical install' {
					set gfxpayload=auto
				linux	/install.amd/vmlinuz desktop=xfce loopback=$iso_path $boot_options -- quiet 
				initrd	/install.amd/gtk/initrd.gz
			}
			submenu '... Xfce advanced options ...' {
				menuentry '... Expert install' {
					set gfxpayload=auto
					linux	/install.amd/vmlinuz desktop=xfce priority=low loopback=$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 loopback=$iso_path $boot_options -- quiet 
					initrd	/install.amd/initrd.gz
				}
				menuentry '... Graphical expert install' {
					set gfxpayload=auto
					linux	/install.amd/vmlinuz desktop=xfce priority=low loopback=$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 loopback=$iso_path $boot_options -- quiet 
					initrd	/install.amd/gtk/initrd.gz
				}
			}
		}
	}
}
menuentry 'Install with speech synthesis' {
	set gfxpayload=auto
	linux	/install.amd/vmlinuz speakup.synth=soft loopback=$iso_path $boot_options -- quiet 
	initrd	/install.amd/gtk/initrd.gz
}

Reply to: