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