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

Bug#724931: PATCH: improved(2) ISO loopmount option



(I see that Andreas has recently posted a set of patches. The patches I
have attached below are not based on that work, although they address
some of the same problems. At the end of this message, are some comments
about how our alternative solutions might be combined.)


On Fri, 4 Oct 2013 06:02:46 -0700
<ian_bruce@fastmail.net> wrote:

> Andreas Cadhalpun <andreas.cadhalpun@googlemail.com> wrote:
> 
>> Sadly it only "seems" to work well, but in fact, your previous (and I
>> assume also this) patch break apt-setup trying to add the CD to
>> /etc/sources.list. I am currently working on this problem and hope to
>> finish this soon.
> 
> I'm sorry to hear that. I'll look into it as well; the error log you
> included in your previous message seemed to indicate that assumptions
> were being made about what block device represented the ISO, or where
> it was mounted. Since the "cdrom-detect" script already figures this
> out, this information just needs to be exported (via a file?) to other
> scripts.

I think the problem is related to this bug:

http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=608201

I have therefore adopted the (partial?) solution which was applied in
that case, which is that ISO images which are found somewhere other than
an actual CD, do not get included in "sources.list". Which seems kind of
unfortunate; the same USB flashdrive could be used again, or an actual
CD might show up later, but that's how they resolved it, and it's not
what we're mainly concerned with right now. If a better solution is
developed sometime later for those situations, it should apply to the
loopmount case as well.

So for now, the solution is to export the fact of the loopmount to the
configuration database, where it can later be checked by the "apt-setup"
package, and handled the same way as the other non-CD cases.

Two patchfiles are attached: a slightly altered one for "cdrom-detect",
and a new one for "apt-setup". I haven't actually tested the latter,
because I'm working with the "netinst" ISO, which doesn't seem to
include that package.

Here are the relevant sections of the installer logs:


    "loopmount=KINGSTON:/linux/debian-7.1.0-amd64-i386-netinst.iso"

Oct  6 07:35:06 cdrom-detect: Searching for Debian installation media...
Oct  6 07:35:06 cdrom-detect: removable devices: (/dev/sr0)
Oct  6 07:35:06 cdrom-detect: LOOPDEV='KINGSTON' LOOPFILE='/linux/debian-7.1.0-amd64-i386-netinst.iso'
Oct  6 07:35:06 cdrom-detect: trying loop-mount on (/dev/disk/by-label/KINGSTON)...
Oct  6 07:35:06 kernel: [  322.483186] FAT-fs (sdf1): utf8 is not a recommended IO charset for FAT filesystems, filesystem will be case sensitive!
Oct  6 07:35:06 kernel: [  322.495521] loop: module loaded
Oct  6 07:35:06 kernel: [  322.571304] ISO 9660 Extensions: Microsoft Joliet Level 3
Oct  6 07:35:06 cdrom-detect: CD-ROM loop-mount succeeded: device=/dev/disk/by-label/KINGSTON/linux/debian-7.1.0-amd64-i386-netinst.iso fstype=iso9660
Oct  6 07:35:06 kernel: [  322.578804] ISO 9660 Extensions: RRIP_1991A
Oct  6 07:35:06 cdrom-detect: Detected CD 'Debian GNU/Linux 7.1.0 "Wheezy" - Official Multi-architecture amd64/i386 NETINST #1 20130615-23:44'
Oct  6 07:35:06 cdrom-detect: Detected CD with 'stable' (wheezy) distribution


    "loopmount=/linux/debian-7.1.0-amd64-i386-netinst.iso"

Oct  6 08:01:19 cdrom-detect: Searching for Debian installation media...
Oct  6 08:01:19 cdrom-detect: removable devices: (/dev/sr0)
Oct  6 08:01:19 cdrom-detect: LOOPDEV='' LOOPFILE='/linux/debian-7.1.0-amd64-i386-netinst.iso'
Oct  6 08:01:19 cdrom-detect: trying loop-mount on (/dev/sda1 /dev/sda10 /dev/sda2 /dev/sda3 /dev/sda4 /dev/sda5 /dev/sda6 /dev/sda7 /dev/sda8 /dev/sda9 /dev/sdb1 /dev/sdb10 /dev/sdb2 /dev/sdb3 /dev/sdb4 /dev/sdb5 /dev/sdb6 /dev/sdb7 /dev/sdb8 /dev/sd
Oct  6 08:01:19 kernel: [  211.616937] FAT-fs (sda1): utf8 is not a recommended IO charset for FAT filesystems, filesystem will be case sensitive!
Oct  6 08:01:19 kernel: [  211.664572] FAT-fs (sda10): utf8 is not a recommended IO charset for FAT filesystems, filesystem will be case sensitive!
Oct  6 08:01:19 kernel: [  211.740574] FAT-fs (sda2): utf8 is not a recommended IO charset for FAT filesystems, filesystem will be case sensitive!
Oct  6 08:01:19 kernel: [  211.804567] FAT-fs (sda3): utf8 is not a recommended IO charset for FAT filesystems, filesystem will be case sensitive!

...

Oct  6 08:01:22 kernel: [  214.316771] FAT-fs (sdf1): utf8 is not a recommended IO charset for FAT filesystems, filesystem will be case sensitive!
Oct  6 08:01:22 kernel: [  214.329130] loop: module loaded
Oct  6 08:01:22 kernel: [  214.399019] ISO 9660 Extensions: Microsoft Joliet Level 3
Oct  6 08:01:22 cdrom-detect: CD-ROM loop-mount succeeded: device=/dev/sdf1/linux/debian-7.1.0-amd64-i386-netinst.iso fstype=iso9660
Oct  6 08:01:22 kernel: [  214.406518] ISO 9660 Extensions: RRIP_1991A
Oct  6 08:01:22 cdrom-detect: Detected CD 'Debian GNU/Linux 7.1.0 "Wheezy" - Official Multi-architecture amd64/i386 NETINST #1 20130615-23:44'
Oct  6 08:01:22 cdrom-detect: Detected CD with 'stable' (wheezy) distribution


(Can these "filesystem will be case sensitive" log messages be shut off,
somehow? Isn't that kind of the point of VFAT?)

-------

Here are my comments on Andreas' latest patches, based on a quick
reading:

I don't know if you have looked at bug #608201; it seems like our
current problem is just another specific case of that general situation,
which awaits a general solution. You can see how it was dealt with
previously by searching for the strings "hybrid" and "usb-hdd" in the
file "apt-setup/generators/40cdrom". It appears that your changes to
that file are similar to mine; however, I think mine are preferable, in
this regard:

I see that you have copied (in this and several other places) this piece
of code, for determining if a loop-mount is being used:

    for arg in $(cat /proc/cmdline); do
        case $arg in
        loopmount=*)
            LOOPMOUNT=${arg#loopmount=}
            LOOPFILE=${LOOPMOUNT#*:}
            [ "$LOOPFILE" != "$LOOPMOUNT" ] && LOOPDEV=${LOOPMOUNT%:*}
            ;;
        esac
    done

Based on my current patches, this is now unnecessary. Do this instead:

    loopmount=$(db_getval cdrom-detect/cdrom_loopdev)

    if [ "$loopmount" ] ; then ... ; else ... ; fi

"$loopmount", if non-null, will contain the actual device (not pathname,
see "$(db_getval cdrom-detect/cdrom_device)" for that) on which the ISO
image file resides, if that is ever useful.

I'm not sure if I understand this:

    if [ "$ROOT" ] && [ "$LOOPMOUNT" ]; then
        save_label
    fi

Does that mean that the ISO will be specified in "sources.list"? If so,
that's valuable. Can that be made to work for the "hybrid" and "usb-hdd"
cases as well? (Search for those strings in "cdrom-detect.postinst" to
see what they mean.)

Your fix for locating firmware images is welcome, with the same comment
as above, about detecting loop-mounts. However, I did not see any
benefit in your changes to "cdrom-detect.postinst". It's easy enough for
somebody to add the proper filesystem types for Hurd and FreeBSD. My
current patch produces slightly more informative log entries, if you
care about that. (see above for examples)

Your work on CD-sets is, of course, important; my patches do not address
that issue.


-- 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-10-06 03:11:34.208545683 -0700
@@ -1,4 +1,8 @@
-#! /bin/sh
+#!/bin/sh
+
+# this should go in /etc/lsb-release or somewhere
+
+DISTRIB_LABEL="Debian 7.1.0 M-A 1"
 
 set -e
 . /usr/share/debconf/confmodule
@@ -14,18 +18,29 @@
 	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
+}
+
 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_loopdev "$loopdev"
 			ret=0
 		else
 			log "The CD in $device is not a Debian CD!"
@@ -33,7 +48,7 @@
 			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
@@ -68,6 +83,7 @@
 		CDFS=iso9660
 		FATFS=vfat
 		OPTIONS=ro,exec
+		LOOPFS=vfat,ext4,iso9660
 		;;
 	hurd)
 		CDFS=iso9660fs
@@ -95,13 +111,27 @@
 
 mkdir /cdrom 2>/dev/null || true
 
+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
+	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
+    log "removable devices: ($devices)"
+    if [ "$devices" ]; then
+      break
     else
       sleep 1
     fi
@@ -109,27 +139,63 @@
 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
+	if [ "$LOOPMOUNT" ]
+	then
+
+		log "LOOPDEV='$LOOPDEV' LOOPFILE='$LOOPFILE'"
+
+		loopfile=/loop/${LOOPFILE#/}
+
+		if [ "$LOOPDEV" ] ; then
+			devices="$(list_devices_by_id "$LOOPDEV")"
+		else
+			devices="$(list-devices partition; list-devices cd)"
 		fi
-	done
 
+		log "trying loop-mount on ($devices)..."
+
+		for loopdev in $devices; do
+			if mount -o $OPTIONS -t $LOOPFS $loopdev /loop; then
+				if [ -f $loopfile ] && try_mount $loopfile $CDFS $OPTIONS $loopdev ; then
+					break 2
+				else
+					umount /loop
+				fi
+			fi
+		done
+
+	else
+
+		# this should wait for a proper solution for bug #608201
+# 		devices="$(list_devices_by_id "$DISTRIB_LABEL")"
+# 		for device in $devices; do
+# 			if try_mount $device $CDFS $OPTIONS; then
+# 				break 2
+# 			fi
+# 		done
+
+		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 +204,7 @@
 	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
--- apt-setup-0.83/generators/40cdrom.orig	2013-05-12 03:49:10.000000000 -0700
+++ apt-setup-0.83/generators/40cdrom	2013-10-05 23:00:57.278336878 -0700
@@ -40,23 +40,29 @@
 	exit 0
 fi
 
-cd_mountable=1
-db_get cdrom-detect/hybrid || true
-if [ "$RET" = true ] || [ -d /hd-media ]; then
+# why isn't this function, or something like it,
+# in /usr/share/debconf/confmodule ?
+
+db_getval()
+{
+	db_get "$1" && echo "$RET" || true
+}
+
+if [ -d /hd-media ] ||
+	[ "$(db_getval cdrom-detect/hybrid)" = true ] ||
+	[ "$(db_getval cdrom-detect/usb-hdd)" = true ] ||
+	[ "$(db_getval cdrom-detect/cdrom_loopdev)" ]
+then
 	cd_mountable=""
 else
-	db_get cdrom-detect/usb-hdd || true
-	if [ "$RET" = true ]; then
-		cd_mountable=""
-	fi
+	cd_mountable=1
 fi
 
-remount_cd() {
+remount_cd()
+{
 	if [ "$ROOT" ] && [ "$cd_mountable" ]; then
-		fs=iso9660
-		if db_get cdrom-detect/cdrom_fs && [ "$RET" ]; then
-			fs="$RET"
-		fi
+		fs=$(db_getval cdrom-detect/cdrom_fs)
+		[ "$fs" ] || fs=iso9660
 		OS=$(udpkg --print-os)
 		case "$OS" in
 			hurd)
@@ -66,8 +72,8 @@
 				OPTIONS=ro,exec
 				;;
 		esac
-		db_get cdrom-detect/cdrom_device
-		$logoutput mount -t "$fs" -o $OPTIONS $RET /cdrom || true
+		device=$(db_getval cdrom-detect/cdrom_device)
+		$logoutput mount -o $OPTIONS -t $fs $device /cdrom || true
 	fi
 }
 

Reply to: