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