Unmounting and 'eject' press

Ikke eikke at eikke.com
Thu Jun 3 04:12:39 PDT 2004

> hi,

> > I looked at the mmc2 draft, and the code you linked to earlier
> >
> > *seems* to do what it should do (altough I couldnt test it myself), and
> > does the hal implementation. The only problem is the limited amount of
> > devices that actually implement the standard I guess...
> I have had to do similar stuff on some proprietary app I worked on. The
> only reasonably portable solution we ended using (after a lot of
> testing) was reproducing the drive state machine in the client
> application by polling every second or half-second with the following
> code. All you have to do is to report state changes to the hal daemon...
> I am by no means an expert but I spent a lot of time making this
> application reliable and this worked very well.
>         /**
>           We use an obsolete feature of INF 8090 which is documented
>           in INF 8020.
>         */
>         command.cmd[0] = 0x5a;
>         command.cmd[1] = 0x00;
>         command.cmd[2] = 0x2a; // code page.
>         command.cmd[3] = 0x00;
>         command.cmd[4] = 0x00;
>         command.cmd[5] = 0x00;
>         command.cmd[6] = 0x00;
>         command.cmd[7] = 0x00;
>         command.cmd[8] = 0x1c;
>         command.cmd[9] = 0x00;
>         command.cmd[10] = 0x00;
>         command.buffer = buffer;
>         command.buflen = 28;
>         command.packetDataDirection = RM_PACKET_DATA_READ;
>         retval = h->packetcommandop (h->handle,&command);
>         if (retval == 0) {
> /* ioctl completed successfully */
>                 media_type_code = buffer[2];
>                 if (media_type_code == 0x71) {
> /* open no disc present */
>                 } else if (media_type_code == 0x70) {
> /* closed  disc present */
>                 } else {
> /* closed no disc present. */
> }
>         }
> Generally, when you want to write such portable code, I would suggest
> you to use the INF8090 and INF8020 specifications rather than the newer
> mmc specfications. These are often better implemented by old and recent
> drives.
> http://www.stanford.edu/~csapuntz/specs/INF-8020.PDF
> ftp://ftp.seagate.com/sff/INF-8090.PDF
> I hope this helps

Thanks for the information. I don't think the actual problem can be solved
by this tough :-s What we actually need is to know when we should eject the
drive (i.e. when the user presses the button). I suppose you're familiar
with *nix systems, so you know, when you want to use a removable volume like
a cdrom, you need to mount it, and the tray gets locked untill the device is
unmounted. So the user is not able to open the tray at all.
What we need is something like this:
- if the disc is not mounted and the user presses 'Eject', the disc is
ejected (thats already the case today)
- if the disc is mounted and not in use, we should in one way or another
detect that the user pressed ejectn unmount it in software, and call the
CDROMEJECT ioctl on the device, so the user can take out the disc
(completely transparent: the user shouldn't know about the unmounting stuff
and so)
- if the disc is mounted and in use, warn the user it's in use, wait untill
it is released by all processes, unmount and eject (or something else,
depends on configuration/implementation). So the big issue is not to know
wether the tray is opened or not, there are standard ioctl call for that if
I'm not mistaken, but to know when we should call umount on the device. And
this seems quite impossible :-s

One possible, but bad solution:
On disc insert, mount the disc, but unlock the tray after that. If the tray
is opened (user pressed eject), a Hal message should be emitted (isn't it?
should test that), or if not, poll (with your code, standard linux code,
whatever) (which is bad behaviour, but well, no other choice). Then we could
check wether the device was still in use by some program, if it was, warn
the user, tell him what program was using the disc, and maybe ask him to
re-insert it. If it wasnt in use anymore, just umount it (propably forced?
Should test too). But this *is* bad behaviour, because processes using the
cd when its ejected could crash or something alike...

I found 2 other things: autorun (SF.net) and mediacheck (Gnome CVS), which
redhat uses/used to accompish some userland automounting stuff. I started
looking at the code, it seems to be quite simple. I also contacted the
autorun author, see on the end of this mail. More information on

Another possible solution:
http://www.uwsg.iu.edu/hypermail/linux/kernel/0308.3/0509.html (bottom of
post). That whole thread has got some usefull information. Maybe I'll
contact  Samphan Raruenrom to ask if he solved it, and if so, how.

David, I compiled
http://www.ussg.iu.edu/hypermail/linux/kernel/0202.0/att-0603/01-cd_poll.c ,
it doesnt run on my cd reader (so I guess tht one isnt mmc2 or Media Status
blablabla compliant), and asked some other people to run it and play around
with their reader. Most of them got messages telling a disc was inserted or
removed, but not whe eject was pressed, so I guess a lot of cdrom players
don't implement mmc2 completely, only some parts (i.e. not the eject part).

Still looking further, but I'm afraid I'll be forced to use "the dirty
method", making the tray unlocking configurable, and trap the EjectPressed
event if configured to do so, i.e. when the drive supports it (using a small
testing app for the user to test if his drive does).

I hope this mail is not too confusing ;-)

Regards, Ikke

[mail from the "autorun" author]
why not use autorun itsself?
[root at jever root]# LANG=C autorun --help
   -e, --notify-eject=STRING  Command STRING will be executed if a CD is
ejected   (default "")

well, if you poll the /dev/cdrom fast enough, you can play around with
different ioctl's:
Returns 1 if a disc has been changed since the last call.

Returns CDS_NO_DISC, if no disc is inserted, or tray is opened

returns CDS_TRAY_OPEN if tray is opened

see also /usr/src/linux-*/Documentation/cdrom/cdrom-standard.tex
hal mailing list
hal at freedesktop.org

More information about the Hal mailing list