[LWN Logo]

Date: Tue, 23 Feb 1999 00:58:18 +0100
From: Jens Axboe <axboe@image.dk>
To: editor@lwn.net, lwn@lwn.net
Subject: O_NONBLOCK, CD-ROM and ioctl

Hi,

I don't know what category this falls under, so I played it safe
and sent it to both. 

I maintain / develop the Uniform layer + ATAPI driver of the
linux kernel and have received some mail regarding this issue
recently. It is imperative that this issue is resolved which
means that some programs must be corrected for proper use with
the 2.2 series kernels. This document will also be submitted
to the maintainers of the related packages for the bigger
distributions, but LWN has a big audience so that might
also help get the word out.

The "message" is below - I'll ofcourse be happy to answer any
questions regarding it.


---> start of message --->

Because of the many bug reports I have received from users switching
to linux-2.2.x, I have decided to write up a small letter explaining
the issue. So if you're either using a CD-ROM or making a program
that utilizes the CD-ROM, read on. That should cover a big part of
the Linux base...

Background information

To understand the problem we need to look at the possible reasons for
opening a device. One, doing normal read/write operations and two,
issuing ioctl commands to the device. With regards to CD-ROM devices,
the former is (naturally) used when mounting data CD's and the latter
when playing audio CD's or when e.g. using eject to spit out the tray.


The problem

For data use we want to check the integrity of the drive and get it
ready for reliable data transfers. This means trying to close the
drive if it seems open (why it would seem open and not be is a
different story), counting tracks, etc. Naturally, this will fail
on an empty tray.


How the problem shows up

All of the below fails with "No medium found" (ENOMEDIUM).
- Doing eject on an empty tray.
- Starting <insert your favorite cd player here> with an empty tray.
- Running hdparm with empty tray.


The solution

To differentiate between these two possible reasons for opening the
device, a special meaning for the O_NONBLOCK flag was devised. In
short, when using O_NONBLOCK as an option flag you are guaranteed
that opening the device will succeed if the CD-ROM device exists.
This deviates from the traditional meaning of this flag, where
it specifies that the driver will not block the calling process
while waiting for completion of a command.


Implementation

Strictly speaking, patching your program is easy. All you need to
do is add O_NONBLOCK to the open() statement:

open("/dev/cdrom", O_RDONLY | O_NONBLOCK);

This goes for all programs that accesses the CD-ROM via ioctl
commands. I am not going to list all the programs that are
"broken" in this sense, mainly because there are so many
different CD-ROM tools, players, etc out there and I simply
don't have the time to check them all.

For further reading consult Documentation/cdrom/cdrom-standard.tex
in you kernel directory - it contains all of the above and much
more.

I'll be happy to answer any questions regarding this issue,
but please cc the author of the program as well.

-- 
*  Jens Axboe <axboe@image.dk>
*  Linux CD-ROM Maintainer
* "The only thing that interferes with my
*  learning is my education." -- A. Einstein