Latest working kernel version: 2.6.24 (maybe later) Earliest failing kernel version: 2.6.27 (maybe earlier) Distribution: Ubuntu 8.10 Hardware Environment: - standard ATAPI CD-ROM drive which works through sr_mod (e. g. PIONEER DVD-RW DVR-212) - not using IDE drivers, but libata and pata (PATA_AMD in my case) Software Environment: - single user mode Problem Description: As reported in https://launchpad.net/bugs/283316 and a couple of duplicates, CD-ROM drives which are opened/ejected immediately close again. This is due to hal polling the device every 2 seconds for an inserted medium for automounting. The reason is that the CDROM_DRIVE_STATUS ioctl now causes an open CD tray to get closed, instead of just returning CDS_TRAY_OPEN and leaving the tray alone (as in earlier kernel releases). Unfortunately I cannot precisely tell at which kernel version it regressed, since the CD drive of my workstation doesn't support mechanical closing (one of those external Dell drives). I built a minimal upstream 2.7.27.2 vanilla kernel with just enough PATA_AMD and SCSI stuff to boot and reproduce this. Given the reported duplicates, it is not specific to a CD ROM drive model or architecture (I reproduced it on x86_64, many reporters are on i386). IANAKD, but a cursory glance at http://git.kernel.org/?p=linux/kernel/git/torvalds/linux-2.6.git;a=history;f=drivers/scsi/sr_ioctl.c revealed that there weren't any changes since about 2.6.24 (where it still worked fine). So I'm afraid I'm lost where to look. Steps to reproduce: - Open CD tray (CD drive must support mechanical closing) - perl -e 'open F, "/dev/scd0"; ioctl (F, 0x5326, 0x7fffffff);'
Does the kernel whine about anything after that?
No, nothing in dmesg. I just found out that the ioctl actually a red herring. The tray already gets closed when merely opening the device: - open CD tray - head < /dev/scd0 bash: /dev/scd0: No medium found
The red herring isn't; opening with O_NDELAY doesn't close the tray (and HAL does set that flag).
(NB: Please change the summary back to "CDROM_DRIVE_STATUS ioctl ..."; I'm not allowed to do that.)
It is actually a combination of open() and ioctl(), it seems. Unfortunately it is not quite as straightforward as I initially thought. I extended the test script a bit to first open() /dev/scd0 with O_NONBLOCK, then wait 5 seconds, then do the ioctl. With that, one can see whether it's actually the open() or the ioctl() that causes the tray to close. Here is how I can reliably reproduce the effect: 1. Clean boot in single user mode without CD-ROM inserted (not necessary, recipe works repeatedly with the same boot, but it helps for having a defined starting point). The important part here is to not have hal running, or anything which interferes with the CD. 2. Open the tray 3. Repeated ./test-eject.pl calls do not close the tray and answers "DRIVE_STATUS: 2" which is TRAY_OPEN. So this works correctly. 4. Insert a CD and close the tray. 5. test-eject.pl returns status 4, does not cause the CD-ROM to spin up, and leaves nothing in dmesg. 6. A second call to test-eject.pl returns status 4, but causes the CD-ROM to spin up and produces a dozen of end_request: I/O error, dev sr0, sector 1428400 Buffer I/O error on device sr0, logical block 178550 dmesg lines. 7. Eject the CD. Now ./test-eject.pl immediately closes the tray (in the open() call), and reports DRIVE_STATUS 1.
OK, so it *is* the open(), not the ioctl(). I dropped the ioctl() from the test script and called it test-eject2.pl which now just does the open(). The steps above work exactly the same with that, after calling it twice it spins up the CD, produces I/O errors, and after ejecting the CD the open() closes the tray.
Created attachment 18399 [details] test-eject.pl (open and ioctl)
Created attachment 18400 [details] test-eject2.pl (open() only)
As for the I/O errors it displays, these are very similar (both text and the block numbers) to what I get if I do "cat /dev/scd0 > /dev/null". It successfully reads the CD, but when the end of the CD is reached, I get a handful of error messages like those, when it tries to read beyond the end of the device. Maybe that's what happens on those open() calls as well?
*sigh* I tried that with a different CD. It seems that the first one was indeed broken. With the second CD, "cat /dev/scd0 > /dev/null" works without producing any I/O errors. Likewise, the test recipe, step 6 does not produce those I/O errors either. The tray still closes, though. So the recipe continues to be valid, just the buffer I/O errors are apparently unrelated to this bug.
Reply-To: James.Bottomley@HansenPartnership.com On Tue, 2008-10-21 at 15:37 -0700, bugme-daemon@bugzilla.kernel.org wrote: > http://bugzilla.kernel.org/show_bug.cgi?id=11803 > > Summary: sr_mod: CDROM_DRIVE_STATUS ioctl causes tray to be > closed > Product: SCSI Drivers > Version: 2.5 > KernelVersion: 2.6.27-2 > Platform: All > OS/Version: Linux > Tree: Mainline > Status: NEW > Severity: normal > Priority: P1 > Component: Other > AssignedTo: scsi_drivers-other@kernel-bugs.osdl.org > ReportedBy: martin.pitt@ubuntu.com > > > Latest working kernel version: 2.6.24 (maybe later) > Earliest failing kernel version: 2.6.27 (maybe earlier) > Distribution: Ubuntu 8.10 > Hardware Environment: > - standard ATAPI CD-ROM drive which works through sr_mod (e. g. PIONEER > DVD-RW > DVR-212) > - not using IDE drivers, but libata and pata (PATA_AMD in my case) > Software Environment: > - single user mode > Problem Description: > > As reported in https://launchpad.net/bugs/283316 and a couple of duplicates, > CD-ROM drives which are opened/ejected immediately close again. This is due > to > hal polling the device every 2 seconds for an inserted medium for > automounting. > > The reason is that the CDROM_DRIVE_STATUS ioctl now causes an open CD tray to > get closed, instead of just returning CDS_TRAY_OPEN and leaving the tray > alone > (as in earlier kernel releases). > > Unfortunately I cannot precisely tell at which kernel version it regressed, > since the CD drive of my workstation doesn't support mechanical closing (one > of > those external Dell drives). > > I built a minimal upstream 2.7.27.2 vanilla kernel with just enough PATA_AMD > and SCSI stuff to boot and reproduce this. Given the reported duplicates, it > is > not specific to a CD ROM drive model or architecture (I reproduced it on > x86_64, many reporters are on i386). > > IANAKD, but a cursory glance at > > http://git.kernel.org/?p=linux/kernel/git/torvalds/linux-2.6.git;a=history;f=drivers/scsi/sr_ioctl.c > revealed that there weren't any changes since about 2.6.24 (where it still > worked fine). So I'm afraid I'm lost where to look. > > Steps to reproduce: > - Open CD tray (CD drive must support mechanical closing) > - perl -e 'open F, "/dev/scd0"; ioctl (F, 0x5326, 0x7fffffff);' I'd finger this commit: commit 210ba1d1724f5c4ed87a2ab1a21ca861a915f734 Author: James Bottomley <James.Bottomley@HansenPartnership.com> Date: Sat Jan 5 10:39:51 2008 -0600 [SCSI] sr: update to follow tray status correctly It's actually a gentoo patch trying to make tray status report with finer detail. Can you revert it and see if the problem goes away? Thanks, James
James, indeed that's it. If I revert it (applies with some fuzz, due to some scsi_ -> sr_ renaming, but trivial), the tray does not close any more. As expected I can now reproduce the original bug, that CDROM_DRIVE_STATUS always returns 2 (CDS_TRAY_OPEN) even if the tray is closed and there is no CD (and it should return 1, CDS_NO_DISC). This is quite obvious, since sr_drive_status() only has those two possible return values. Thank you!
I did some further bisectioning. If I revert the lower part of the patch (everything at and after "return CDS_TRAY_OPEN;"), and thus just replace test_unit_ready() by sr_test_unit_ready() (as it is in current kernel), I still get the bug. This lower part was introduced to handle the further cases of TRAY_OPEN/NO_DISC, which that gentoo bug complained about. So it seems that sr_test_unit_ready() is to blame here.
If I use scsi_ready() (as in the original patch) instead of sr_test_unit_ready(), the tray stays open, but scsi_test_unit_ready() *always* returns 0, so that the ioctl always answers with 4/DISC_OK. So {sr,scsi}_test_unit_ready() are not quite as identical as sr_test_unit_ready()'s comment claims... That might be a good data point for further inquiries. OTOH, if I revert to test_unit_ready() and additionally keep the cdrom_get_media_event() call (and just eliminate the special cases below, which need sshdr), I also get the tray closing. In this case, the return values are correct at least.
Ah, mea culpa for the noise. It seems that this this actually an udev problem after all: http://git.kernel.org/?p=linux/hotplug/udev.git;a=commitdiff;h=f755fd5657b619fd27160ad202fc5d773d096e9c So it seems that the last ioctl kernel patch referenced above just fixed the return status enough to make the emitted change events actually work, so that udev's rules would kick in.