Hello,

I found a better solution for ejecting the CD than the shutdown helper that we have now. This should work even for software suspend purposes (where the current helper is useless). Below is an annotated quotation from my bash history that illustrates the idea.

I inserted the CD into /dev/cdrom1 and mounted it as /media/cdrom1.

losetup /dev/loop4 /media/cdrom1/root.ext2
dd if=/dev/null of=/dev/shm/.overlay bs=1M seek=256
losetup /dev/loop5 /dev/shm/.overlay

This created two loop devices: /dev/loop4 is read-only, /dev/loop5 is for writing changed data to the overlay.

echo 0 `blockdev --getsize /dev/loop4` linear /dev/loop4 0 | dmsetup create lfs-buffer

This is new as compared to the current LiveCD boot procedure. The effect is that /dev/mapper/lfs-buffer has the same contents as /dev/loop4, and is read-only. Think of it as yet another loop device that can be later reconfigured on the fly.

echo 0 `blockdev --getsize /dev/loop4` snapshot /dev/mapper/lfs-buffer /dev/loop5 p 8 | dmsetup create lfs-cd

This is the same as we have in the binary init, except we use /dev/mapper/lfs-buffer instead of using /dev/loop4 directly. Result: /dev/mapper/lfs-cd is a read-write device that initially has the same contents as root.ext2 on the CD.

mount -t ext2 /dev/mapper/lfs-cd /mnt/image

This is done just to make the device busy.

touch /mnt/image/test1
ls -l /mnt/image
<snip output>

This is done just to verify the setup.

dmsetup suspend lfs-cd

This is the main trick. From now on, reading and writing to /dev/mapper/lfs-cd blocks until we resume the device.

echo 0 `blockdev --getsize /dev/loop4` error | dmsetup load lfs-buffer
dmsetup resume lfs-buffer

This reconfigures lfs-buffer to give errors for every operation (but there will be no operations). As a side effect, /dev/loop4 becomes free.

losetup -d /dev/loop4
umount /media/cdrom1

Indeed, we can free it and unmount the CD (and even take it). /mnt/image is still mounted, but every operation there has to wait. Then I inserted the CD back.

mount /media/cdrom1
losetup /dev/loop4 /media/cdrom1/root.ext2

And set up the loop device again.

echo 0 `blockdev --getsize /dev/loop4` linear /dev/loop4 0 | dmsetup load lfs-buffer
dmsetup resume lfs-buffer

This loaded the original mapping to /dev/loop4 into /dev/mapper/lfs-buffer.

dmsetup resume lfs-cd

This made /dev/mapper/lfs-cd work again.

ls -l /mnt/image
<snip output>

That works too.

umount /mnt/image
dmsetup remove lfs-cd
dmsetup remove lfs-buffer
losetup -d /dev/loop5
losetup -d /dev/loop4
umount /media/cdrom1

That's the required cleanup procedure before finally ejecting the CD.

Resume: a way has been found to reliably eject a CD compressed with the same scheme as the current LFS LiveCD without unmounting the magic read-write block device and without "busy inodes on changed media" error in dmesg.

However, in order to apply this to the LiveCD, this has to be turned into a binary that does mlockall() and chroots to /dev/shm, because all access attempts to the root filesystem will deadlock while /dev/mapper/lfs-cd is suspended. I am going to implement this binary during the next week.

--
Alexander E. Patrakov
--
http://linuxfromscratch.org/mailman/listinfo/livecd
FAQ: http://www.linuxfromscratch.org/faq/
Unsubscribe: See the above information page

Reply via email to