FS#25405 - [eject] CD/DVD tray can not be ejected by user if locked

Attached to Project: Arch Linux
Opened by Natrio (natrio) - Friday, 05 August 2011, 06:52 GMT
Last edited by Tom Gundersen (tomegun) - Saturday, 20 August 2011, 15:22 GMT
Task Type Bug Report
Category Packages: Core
Status Closed
Assigned To Tobias Powalowski (tpowa)
Roman Kyrylych (Romashka)
Tom Gundersen (tomegun)
Architecture i686
Severity Medium
Priority Normal
Reported Version
Due in Version Undecided
Due Date Undecided
Percent Complete 100%
Votes 0
Private No

Details

Description:
The command "eject" no longer works from a user but works from the root.
"eject -t" still works.
"sdparm -vC eject /dev/sr0" answers "Medium removal prevented".
After "sdparm -C unlock /dev/sr0" command "eject" works once again.
Rolling back to "udev-171-2" fixes the problem.

Additional info:
* package version(s) 173-3

Logs:
-------------------
$ eject -v
eject: using default device `cdrom'
eject: device name is `cdrom'
eject: expanded name is `/dev/cdrom'
eject: `/dev/cdrom' is a link to `/dev/sr0'
eject: `/dev/sr0' is not mounted
eject: `/dev/sr0' is not a mount point
eject: `/dev/sr0' is not a multipartition device
eject: trying to eject `/dev/sr0' using CD-ROM eject command
eject: CD-ROM eject command failed
eject: trying to eject `/dev/sr0' using SCSI commands
eject: SCSI eject failed
eject: trying to eject `/dev/sr0' using floppy eject command
eject: floppy eject command failed
eject: trying to eject `/dev/sr0' using tape offline command
eject: tape offline command failed
eject: unable to eject, last error: Inappropriate ioctl for device
-------------------
$ sdparm -vC eject /dev/sr0
>>> about to open device name: /dev/sr0
/dev/sr0: SONY DVD RW DW-Q120A PYS3 [cd/dvd]
Start stop unit command: 1b 00 00 00 02 00
start stop unit: Fixed format, current; Sense key: Illegal Request
Additional sense: Medium removal prevented
-------------------
~$ sdparm -vC unlock /dev/sr0
>>> about to open device name: /dev/sr0
/dev/sr0: SONY DVD RW DW-Q120A PYS3 [cd/dvd]
Prevent allow medium removal cdb: 1e 00 00 00 00 00
-------------------
$ eject -v
eject: using default device `cdrom'
eject: device name is `cdrom'
eject: expanded name is `/dev/cdrom'
eject: `/dev/cdrom' is a link to `/dev/sr0'
eject: `/dev/sr0' is not mounted
eject: `/dev/sr0' is not a mount point
eject: `/dev/sr0' is not a multipartition device
eject: trying to eject `/dev/sr0' using CD-ROM eject command
eject: CD-ROM eject command succeeded
-------------------
This task depends upon

Closed by  Tom Gundersen (tomegun)
Saturday, 20 August 2011, 15:22 GMT
Reason for closing:  Fixed
Additional comments about closing:  Thansk a lot Natrio for your help!
Comment by Natrio (natrio) - Friday, 05 August 2011, 07:41 GMT
Sorry, I forgot two things:
1) To reproduce the problem, cd/dvd-DISK must be INSERTED INTO, the tray must be NOT empty.
2) It has not been tested on SATA-devices, I have a IDE-drive.
Comment by Tom Gundersen (tomegun) - Friday, 05 August 2011, 12:33 GMT
What does ls -la /dev/sr0 say? What groups are you in? Do you use console-kit or systemd?
Comment by Natrio (natrio) - Friday, 05 August 2011, 21:30 GMT
Yes, I am in the group "optical", and of course,
brw-rw----+ 1 root optical 11, 0 Aug 5 19:34 /dev/sr0
No, I do not use systemd, and console-kit does not change anything.
I already wrote above that "eject-t" works, and downgrade udev fixes this.
http://www.spinics.net/lists/hotplug/msg05030.html
Quite: "udev 172
========
Bugfixes.

Udev now enables kernel media-presence polling if available. Part
of udisks optical drive tray-handling moved to cdrom_id: The tray
is locked as soon as a media is detected to enable the receiving
of media-eject-request events. Media-eject-request events will
eject the media."
This is the case, right?
Comment by Tom Gundersen (tomegun) - Friday, 05 August 2011, 21:39 GMT
Ah, of course (I was only thinking of the changes between 172 and 173, so forgot the polling stuff).

Could you try "udisks --eject /dev/sr0" to see if that works?
Comment by Tom Gundersen (tomegun) - Friday, 05 August 2011, 21:51 GMT
By the way: I can reproduce the problem with eject, and using udisks works for me.
Comment by Natrio (natrio) - Friday, 05 August 2011, 21:53 GMT
"udisks --eject /dev/sr0" works, but it runs through udisks-daemon, which runs as root.
Comment by Tom Gundersen (tomegun) - Friday, 05 August 2011, 23:20 GMT
I guess eject should unlock the drive before trying to eject it (I don't know why this works as root, but I haven't looked into what the kernel does). I got some more output (I have a SCSI drive):

As user:
ioctl(3, SG_GET_VERSION_NUM, 0x7fffce47b7ac) = 0
ioctl(3, SG_IO, {'S', SG_DXFER_NONE, cmd[6]=[1e, 00, 00, 00, 00, 00], mx_sb_len=32, iovec_count=0, dxfer_len=0, timeout=2000, flags=0}) = -1 EFAULT (Bad address)
eject: unable to eject, last error: Bad address

As root:
ioctl(3, SG_GET_VERSION_NUM, 0x7fff688643ac) = 0
ioctl(3, SG_IO, {'S', SG_DXFER_NONE, cmd[6]=[1e, 00, 00, 00, 00, 00], mx_sb_len=32, iovec_count=0, dxfer_len=0, timeout=2000, flags=0, status=00, masked_status=00, sb[0]=[], host_status=0, driver_status=0, resid=0, duration=0, info=0}) = 0
ioctl(3, SG_IO, {'S', SG_DXFER_NONE, cmd[6]=[1b, 00, 00, 00, 01, 00], mx_sb_len=32, iovec_count=0, dxfer_len=0, timeout=2000, flags=0, status=00, masked_status=00, sb[0]=[], host_status=0, driver_status=0, resid=0, duration=1980, info=0}) = 0
ioctl(3, SG_IO, {'S', SG_DXFER_NONE, cmd[6]=[1b, 00, 00, 00, 02, 00], mx_sb_len=32, iovec_count=0, dxfer_len=0, timeout=2000, flags=0, status=00, masked_status=00, sb[0]=[], host_status=0, driver_status=0, resid=0, duration=3600, info=0}) = 0
ioctl(3, BLKRRPART, 0x7fff68864230) = -1 EINVAL (Invalid argument)

The second one succeeds (even though the last ioctl returns an error), and the first one fails.

It would be great if you could also get a trace for the IDE case. Please install "strace" and do (both as user and as root):

strace -e ioctl eject -r /dev/sr0

Looking at the sourecode, I think your output will be easier to understand as the CDROM ioctl is much simpler than the SCSI one.
Comment by Tom Gundersen (tomegun) - Friday, 05 August 2011, 23:26 GMT
Oh, and if you could also do an strace of "sdparm -C unlock /dev/sr0" call, you'll know what IOCTL needs to be called from EjectCdrom() in eject.c of the eject package ;-)
Comment by Natrio (natrio) - Monday, 08 August 2011, 11:14 GMT
As user:
----------------- CD-ROM eject (failed), unlock, CD-ROM eject (succeeded) -----------------
$ strace -e ioctl eject -r /dev/sr0
ioctl(3, CDROMEJECT, 0x804b86c) = -1 EIO (Input/output error)
eject: unable to eject, last error: Input/output error
$ strace -e ioctl sdparm -C unlock /dev/sr0
ioctl(3, SG_IO, {'S', SG_DXFER_FROM_DEV, cmd[6]=[12, 00, 00, 00, 24, 00], mx_sb_len=32, iovec_count=0, dxfer_len=36, timeout=60000, flags=0, data[36]=["\5\200\0052[\0\0\0SONY DVD RW DW-Q120A "...], status=00, masked_status=00, sb[0]=[], host_status=0, driver_status=0, resid=0, duration=0, info=0}) = 0
/dev/sr0: SONY DVD RW DW-Q120A PYS3 [cd/dvd]
ioctl(3, SG_IO, {'S', SG_DXFER_NONE, cmd[6]=[1e, 00, 00, 00, 00, 00], mx_sb_len=32, iovec_count=0, dxfer_len=0, timeout=60000, flags=0, status=00, masked_status=00, sb[0]=[], host_status=0, driver_status=0, resid=0, duration=0, info=0}) = 0
$ strace -e ioctl eject -r /dev/sr0
ioctl(3, CDROMEJECT, 0x804b86c) = 0
----------------- (cut end) -----------------

And this proved to be even more interesting than I expected.
The "CD-ROM eject" command (without unlock) does not work not only as a user, and as root also fails.
But the SCSI command works as root, which does not work under the user.

As root:
----------------- CD-ROM eject (failed), SCSI eject (succeeded) -----------------
# strace -e ioctl eject -r /dev/sr0
ioctl(3, CDROMEJECT, 0x804b86c) = -1 EIO (Input/output error)
eject: unable to eject, last error: Input/output error
# strace -e ioctl eject -s /dev/sr0
ioctl(3, SG_GET_VERSION_NUM, 0xbf8d4af8) = 0
ioctl(3, SG_IO, {'S', SG_DXFER_NONE, cmd[6]=[1e, 00, 00, 00, 00, 00], mx_sb_len=32, iovec_count=0, dxfer_len=0, timeout=2000, flags=0, status=00, masked_status=00, sb[0]=[], host_status=0, driver_status=0, resid=0, duration=0, info=0}) = 0
ioctl(3, SG_IO, {'S', SG_DXFER_NONE, cmd[6]=[1b, 00, 00, 00, 01, 00], mx_sb_len=32, iovec_count=0, dxfer_len=0, timeout=2000, flags=0, status=00, masked_status=00, sb[0]=[], host_status=0, driver_status=0, resid=0, duration=3, info=0}) = 0
ioctl(3, SG_IO, {'S', SG_DXFER_NONE, cmd[6]=[1b, 00, 00, 00, 02, 00], mx_sb_len=32, iovec_count=0, dxfer_len=0, timeout=2000, flags=0, status=00, masked_status=00, sb[0]=[], host_status=0, driver_status=0, resid=0, duration=2436, info=0}) = 0
ioctl(3, BLKRRPART, 0xbf8d4a78) = -1 EINVAL (Invalid argument)
----------------- (cut end) -----------------

As user:
----------------- SCSI eject (failed) -----------------
$ strace -e ioctl eject -s /dev/sr0
ioctl(3, SG_GET_VERSION_NUM, 0xbfcc75d8) = 0
ioctl(3, SG_IO, {'S', SG_DXFER_NONE, cmd[6]=[1e, 00, 00, 00, 00, 00], mx_sb_len=32, iovec_count=0, dxfer_len=0, timeout=2000, flags=0}) = -1 EFAULT (Bad address)
eject: unable to eject, last error: Bad address
----------------- (cut end) -----------------
Comment by Tom Gundersen (tomegun) - Monday, 08 August 2011, 11:21 GMT
Thanks' for getting back with more info. I'll assign this to eject for now, as I think the correct thing is for eject to just unlock the device before trying to eject it.

I'm still a bit puzzled why this works as root, even without unlocking first.
Comment by Natrio (natrio) - Monday, 08 August 2011, 11:42 GMT
Thank you, this is all very interesting, but it remains one little problem.
The command "eject" does not know how to unlock a locked tray, because it should not be locked.
CD-ROM should not be automatically locked at all.

But I see:
-----------------
# ps aux|grep udev
root 266 0.0 0.1 2596 1252 ? Ss 13:02 0:00 udevd --daemon
root 337 0.0 0.1 2592 1040 ? S 13:02 0:00 udevd --daemon
root 338 0.0 0.0 2592 948 ? S 13:02 0:00 udevd --daemon
root 2905 0.0 0.0 5668 832 pts/0 S+ 15:34 0:00 grep udev
# strace -e ioctl -f -p 337
..........................
Process 2792 attached (waiting for parent)
Process 2792 resumed (parent 337 ready)
[pid 2792] ioctl(3, CDROM_GET_CAPABILITY or SNDRV_SEQ_IOCTL_UNSUBSCRIBE_PORT, 0) = 3800047
[pid 2792] ioctl(3, CDROM_DRIVE_STATUS, 0x7fffffff) = 4
[pid 2792] ioctl(3, SG_IO, {'S', SG_DXFER_FROM_DEV, cmd[6]=[12, 00, 00, 00, 24, 00], mx_sb_len=64, iovec_count=0, dxfer_len=36, timeout=0, flags=0x3, data[36]=["\5\200\0052[\0\0\0SONY DVD RW DW-Q120A "...], status=00, masked_status=00, sb[0]=[], host_status=0, driver_status=0, resid=0, duration=0, info=0}) = 0
[pid 2792] ioctl(3, SG_IO, {'S', SG_DXFER_FROM_DEV, cmd[10]=[46, 00, 00, 00, 00, 00, 00, 00, 08, 00], mx_sb_len=64, iovec_count=0, dxfer_len=8, timeout=0, flags=0x3, data[8]=["\0\0\1@\0\0\0\t"], status=00, masked_status=00, sb[0]=[], host_status=0, driver_status=0, resid=0, duration=13, info=0}) = 0
[pid 2792] ioctl(3, SG_IO, {'S', SG_DXFER_FROM_DEV, cmd[10]=[46, 00, 00, 00, 00, 00, 00, 01, 40, 00], mx_sb_len=64, iovec_count=0, dxfer_len=320, timeout=0, flags=0x3, data[320]=["\0\0\1@\0\0\0\t\0\0\0030\0+\0\0\0\33\0\0\0\32\0\0\0\26\0\0\0\25\0\0"...], status=00, masked_status=00, sb[0]=[], host_status=0, driver_status=0, resid=0, duration=20, info=0}) = 0
[pid 2792] ioctl(3, SG_IO, {'S', SG_DXFER_FROM_DEV, cmd[10]=[43, 00, 00, 00, 00, 00, 01, 00, 0c, 00], mx_sb_len=64, iovec_count=0, dxfer_len=12, timeout=0, flags=0x3, data[12]=["\0\22\1\1\0\24\1\0\0\0\0\0"], status=00, masked_status=00, sb[0]=[], host_status=0, driver_status=0, resid=0, duration=0, info=0}) = 0
[pid 2792] ioctl(3, SG_IO, {'S', SG_DXFER_FROM_DEV, cmd[10]=[43, 00, 00, 00, 00, 00, 01, 00, 14, 00], mx_sb_len=64, iovec_count=0, dxfer_len=20, timeout=0, flags=0x3, data[20]=["\0\22\1\1\0\24\1\0\0\0\0\0\0\24\252\0\0\5u\345"], status=00, masked_status=00, sb[0]=[], host_status=0, driver_status=0, resid=0, duration=3, info=0}) = 0
[pid 2792] ioctl(3, SG_IO, {'S', SG_DXFER_FROM_DEV, cmd[10]=[43, 00, 01, 00, 00, 00, 00, 00, 0c, 00], mx_sb_len=64, iovec_count=0, dxfer_len=12, timeout=0, flags=0x3, data[12]=["\0\n\1\1\0\24\1\0\0\0\0\0"], status=00, masked_status=00, sb[0]=[], host_status=0, driver_status=0, resid=0, duration=0, info=0}) = 0
[pid 2792] ioctl(3, SG_IO, {'S', SG_DXFER_FROM_DEV, cmd[10]=[51, 00, 00, 00, 00, 00, 00, 00, 20, 00], mx_sb_len=64, iovec_count=0, dxfer_len=32, timeout=0, flags=0x3, data[32]=["\0 \16\1\1\1\1\200\0\0\0\0\0\r\17J\377\377\377\377\377\377\377\377\0\0\0\0\0\0\0\0"], status=00, masked_status=00, sb[0]=[], host_status=0, driver_status=0, resid=0, duration=13, info=0}) = 0
[pid 2792] ioctl(3, CDROM_CLEAR_OPTIONS or SNDRV_SEQ_IOCTL_DELETE_PORT, 0x8) = 5
[pid 2792] ioctl(3, CDROM_LOCKDOOR, 0x1) = 0
Process 2792 detached
Process 2793 attached
[pid 2793] ioctl(3, SG_IO, {'Q', 0 /* SG_DXFER_??? */, cmd[0]=[], mx_sb_len=0, iovec_count=0, dxfer_len=12, timeout=0, flags=0}) = -1 EINVAL (Invalid argument)
[pid 2793] ioctl(3, SG_IO, {'S', SG_DXFER_FROM_DEV, cmd[12]=[12, 00, 00, 00, 24, 00, 00, 00, 00, 00, 00, 00], mx_sb_len=32, iovec_count=0, dxfer_len=36, timeout=30000, flags=0, data[36]=["\5\200\0052[\0\0\0SONY DVD RW DW-Q120A "...], status=00, masked_status=00, sb[0]=[], host_status=0, driver_status=0, resid=0, duration=0, info=0}) = 0
[pid 2793] ioctl(3, SG_IO, {'Q', 0 /* SG_DXFER_??? */, cmd[0]=[], mx_sb_len=0, iovec_count=0, dxfer_len=16, timeout=0, flags=0}) = -1 EINVAL (Invalid argument)
[pid 2793] ioctl(3, SG_IO, {'S', SG_DXFER_FROM_DEV, cmd[16]=[85, 08, 2e, 00, 00, 00, 01, 00, 00, 00, 00, 00, 00, 00, a1, 00], mx_sb_len=32, iovec_count=0, dxfer_len=512, timeout=30000, flags=0, data[512]=["\300\205\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0 "...], status=02, masked_status=01, sb[22]=[72, 00, 00, 00, 00, 00, 00, 0e, 09, 0c, 00, 00, 00, 02, 00, 00, 00, 00, 00, 02, 00, 50], host_status=0, driver_status=0x8, resid=0, duration=13, info=0x1}) = 0
Process 2793 detached
..........................
Comment by Tom Gundersen (tomegun) - Monday, 08 August 2011, 11:46 GMT
Udev does indeed lock the cdrom drive by default when a medium is inserted. This is, as far as I understand, the intended behavior. Why do you say that it should not do this?
Comment by Tom Gundersen (tomegun) - Monday, 08 August 2011, 12:04 GMT
Looking again at the ioctl that fails:

as user:
ioctl(3, SG_IO, {'S', SG_DXFER_NONE, cmd[6]=[1e, 00, 00, 00, 00, 00], mx_sb_len=32, iovec_count=0, dxfer_len=0, timeout=2000, flags=0}) = -1 EFAULT (Bad address)

as root:
ioctl(3, SG_IO, {'S', SG_DXFER_NONE, cmd[6]=[1e, 00, 00, 00, 00, 00], mx_sb_len=32, iovec_count=0, dxfer_len=0, timeout=2000, flags=0, status=00, masked_status=00, sb[0]=[], host_status=0, driver_status=0, resid=0, duration=0, info=0}) = 0

This corresponds to the source code:

struct sdata {
int inlen;
int outlen;
char cmd[256];
} scsi_cmd;

scsi_cmd.inlen = 0;
scsi_cmd.outlen = 0;
scsi_cmd.cmd[0] = ALLOW_MEDIUM_REMOVAL;
scsi_cmd.cmd[1] = 0;
scsi_cmd.cmd[2] = 0;
scsi_cmd.cmd[3] = 0;
scsi_cmd.cmd[4] = 0;
scsi_cmd.cmd[5] = 0;
status = ioctl(fd, SCSI_IOCTL_SEND_COMMAND, (void *)&scsi_cmd);

Which should be equivalent "sg_prevent --allow /dev/sr0". Indeed, trying as user:

% strace -e ioctl sg_prevent --allow /dev/sr0
ioctl(3, SG_IO, {'S', SG_DXFER_NONE, cmd[6]=[1e, 00, 00, 00, 00, 00], mx_sb_len=32, iovec_count=0, dxfer_len=0, timeout=60000, flags=0, status=00, masked_status=00, sb[0]=[], host_status=0, driver_status=0, resid=0, duration=0, info=0}) = 0


In other words, if the exact same ioctl is used as user as is used as root, it works as intended, and eject can eject a locked device.

The question is: why is eject treating user and root differently?
Comment by Natrio (natrio) - Monday, 08 August 2011, 12:45 GMT
Sorry, you certainly do not fault that udev developers decided to arrogate to itself the right to block CD-ROM on my computer.

Ok, let's we look at sdparm.
Finally, sdparm (ar root!) can't eject without unlock, but the command "eject -s" can. Obviously, the latter produces some sort of action beyond default eject?

As root:
----------------- eject (failed), unlock, eject (succeeded)
# strace -e ioctl sdparm -C eject /dev/sr0
ioctl(3, SG_IO, {'S', SG_DXFER_FROM_DEV, cmd[6]=[12, 00, 00, 00, 24, 00], mx_sb_len=32, iovec_count=0, dxfer_len=36, timeout=60000, flags=0, data[36]=["\5\200\0052[\0\0\0SONY DVD RW DW-Q120A "...], status=00, masked_status=00, sb[0]=[], host_status=0, driver_status=0, resid=0, duration=3, info=0}) = 0
/dev/sr0: SONY DVD RW DW-Q120A PYS3 [cd/dvd]
ioctl(3, SG_IO, {'S', SG_DXFER_NONE, cmd[6]=[1b, 00, 00, 00, 02, 00], mx_sb_len=32, iovec_count=0, dxfer_len=0, timeout=120000, flags=0, status=02, masked_status=01, sb[18]=[70, 00, 05, 00, 00, 00, 00, 0a, 00, 00, 00, 00, 53, 02, 00, 00, 00, 00], host_status=0, driver_status=0x8, resid=0, duration=0, info=0x1}) = 0
# strace -e ioctl sdparm -C unlock /dev/sr0
ioctl(3, SG_IO, {'S', SG_DXFER_FROM_DEV, cmd[6]=[12, 00, 00, 00, 24, 00], mx_sb_len=32, iovec_count=0, dxfer_len=36, timeout=60000, flags=0, data[36]=["\5\200\0052[\0\0\0SONY DVD RW DW-Q120A "...], status=00, masked_status=00, sb[0]=[], host_status=0, driver_status=0, resid=0, duration=0, info=0}) = 0
/dev/sr0: SONY DVD RW DW-Q120A PYS3 [cd/dvd]
ioctl(3, SG_IO, {'S', SG_DXFER_NONE, cmd[6]=[1e, 00, 00, 00, 00, 00], mx_sb_len=32, iovec_count=0, dxfer_len=0, timeout=60000, flags=0, status=00, masked_status=00, sb[0]=[], host_status=0, driver_status=0, resid=0, duration=0, info=0}) = 0
# strace -e ioctl sdparm -C eject /dev/sr0
ioctl(3, SG_IO, {'S', SG_DXFER_FROM_DEV, cmd[6]=[12, 00, 00, 00, 24, 00], mx_sb_len=32, iovec_count=0, dxfer_len=36, timeout=60000, flags=0, data[36]=["\5\200\0052[\0\0\0SONY DVD RW DW-Q120A "...], status=00, masked_status=00, sb[0]=[], host_status=0, driver_status=0, resid=0, duration=0, info=0}) = 0
/dev/sr0: SONY DVD RW DW-Q120A PYS3 [cd/dvd]
ioctl(3, SG_IO, {'S', SG_DXFER_NONE, cmd[6]=[1b, 00, 00, 00, 02, 00], mx_sb_len=32, iovec_count=0, dxfer_len=0, timeout=120000, flags=0, status=00, masked_status=00, sb[0]=[], host_status=0, driver_status=0, resid=0, duration=2843, info=0}) = 0
-----------------
Comment by Tom Gundersen (tomegun) - Monday, 08 August 2011, 13:53 GMT
Yes. eject first unlocks before ejecting. The question is why this fails as user, for some reason it is not sending the same request to the kernel. This clearly is possible as shown in my last message, using sg_prevent.

Regarding udev: If you can convince me that udev is doing the wrong thing I can take it up with the udev dev's. They are very reasonable, so if you have a technically sound argument, then I guess there will not be a problem to convince them. However, it is not clear to me why you think udev is doing the wrong thing. It seems the dev's did this on purpose, so I can only assume they had good reason to.
Comment by Natrio (natrio) - Tuesday, 09 August 2011, 10:22 GMT
I figured out why the "eject -s" works as root only. Our mistake was that we looked at the strace only "ioctl()" calls. I watched the entire dump, and found this:
----------
$ strace -e open,ioctl,close eject -s /dev/sr0
open("/etc/ld.so.cache", O_RDONLY) = 3
close(3) = 0
open("/lib/libc.so.6", O_RDONLY) = 3
close(3) = 0
open("/etc/mtab", O_RDONLY) = 3
close(3) = 0
open("/etc/fstab", O_RDONLY) = 3
close(3) = 0
open("/dev/sr0", O_RDONLY|O_NONBLOCK) = 3
ioctl(3, SG_GET_VERSION_NUM, 0xbf934708) = 0
ioctl(3, SG_IO, {'S', SG_DXFER_NONE, cmd[6]=[1e, 00, 00, 00, 00, 00], mx_sb_len=32, iovec_count=0, dxfer_len=0, timeout=60000, flags=0}) = -1 EFAULT (Bad address)
eject: unable to eject, last error: Bad address
$ strace -e open,ioctl,close sdparm -C unlock /dev/sr0
open("/etc/ld.so.cache", O_RDONLY) = 3
close(3) = 0
open("/lib/libc.so.6", O_RDONLY) = 3
close(3) = 0
open("/proc/devices", O_RDONLY) = 3
close(3) = 0
open("/dev/sr0", O_RDWR|O_NONBLOCK) = 3
ioctl(3, SG_IO, {'S', SG_DXFER_FROM_DEV, cmd[6]=[12, 00, 00, 00, 24, 00], mx_sb_len=32, iovec_count=0, dxfer_len=36, timeout=60000, flags=0, data[36]=["\5\200\0052[\0\0\0SONY DVD RW DW-Q120A "...], status=00, masked_status=00, sb[0]=[], host_status=0, driver_status=0, resid=0, duration=0, info=0}) = 0
/dev/sr0: SONY DVD RW DW-Q120A PYS3 [cd/dvd]
ioctl(3, SG_IO, {'S', SG_DXFER_NONE, cmd[6]=[1e, 00, 00, 00, 00, 00], mx_sb_len=32, iovec_count=0, dxfer_len=0, timeout=60000, flags=0, status=00, masked_status=00, sb[0]=[], host_status=0, driver_status=0, resid=0, duration=0, info=0}) = 0
close(3) = 0
----------
---------- from eject.c ----------
/* Open a device file. */
static int OpenDevice(const char *fullName)
{
int fd = open(fullName, O_RDONLY|O_NONBLOCK);
----------
When I made the "eject" to open the device to write (O_RDWR, copyed from sdparm's strace dump), it started to work as user.

You can see that in SCSI mode command "eject" will unlock the first, and then ejects the media:
---------- from eject.c ----------
static int EjectScsi(int fd)
{
int status, k;
sg_io_hdr_t io_hdr;
unsigned char allowRmBlk[6] = {ALLOW_MEDIUM_REMOVAL, 0, 0, 0, 0, 0};
unsigned char startStop1Blk[6] = {START_STOP, 0, 0, 0, 1, 0};
unsigned char startStop2Blk[6] = {START_STOP, 0, 0, 0, 2, 0};
----------

But in CD-ROM mode "eject" does not attempt to unlock the tray:
---------- from eject.c ----------
static int EjectCdrom(int fd)
{
int status = -1;

#if defined(CDROMEJECT)
status = ioctl(fd, CDROMEJECT);
----------
I inserted a call "ioctl(fd, CDROM_LOCKDOOR, 0);" in the beginning of the EjectCdrom() and ToggleTray() functions, and they began to have work successfully under the newly mutated udev>=172.

Now that we've finally figured out the "eject", we can return to udev :)

P.S.
The "CDROMEJECT" call really does not work on SCSI? I have it even works on usb-flash. As far as I know, it is SCSI over USB.
Comment by Natrio (natrio) - Wednesday, 10 August 2011, 16:42 GMT
I found the implementation of the ioctl() call "CDROMEJECT" in the kernel module "cdrom".

http://git.kernel.org/?p=linux/kernel/git/stable/linux-3.0.y.git;a=blob;f=drivers/cdrom/cdrom.c;h=75fb965b8f72b1e9fa2a8001f7fb16fb12388d5c;hb=HEAD#l2287

Now I understand why "eject" did not try to unlock the tray in CD-ROM mode. This module is automatically unlock the drive before ejecting! But now call "CDROMEJECT" no longer comes to this module and processed somewhere else, and unlock requires separately in this mode.
Comment by Tom Gundersen (tomegun) - Wednesday, 10 August 2011, 16:56 GMT
@natrio: thanks for looking into this more. It seems that this could and should be fixed in eject, so maybe it is worth contacting the eject upstream maintainer?
Comment by Natrio (natrio) - Wednesday, 10 August 2011, 19:25 GMT
http://projects.archlinux.org/svntogit/packages.git/tree/eject/trunk/PKGBUILD
Please note the version and location of the package version with source code.
It is on the server ftp.archlinux.org, and version is 2.1.5.
On the upstream site latest version is 2.1.0, and it's dated 2005.
It seems that link to upstream is lost a long time.

I will prepare a patch and post it here.
Comment by Natrio (natrio) - Thursday, 11 August 2011, 09:24 GMT
This is my patch.
It adds an attempt to open device for R/W (otherwise SCSI commands don't work as user) and a new function UnlockCdrom(), whitch unlocks a tray in CD-ROM mode before ejecting.
Comment by Tom Gundersen (tomegun) - Thursday, 11 August 2011, 09:57 GMT
@natrio: Thanks! I'll follow up on this and see what we can do to get this fixed.

Just one question: you mention "newer kernels" do you happen to know the git commit when this changed? If not I'll try to find it myself, to better understand why the behavior changed.
Comment by Natrio (natrio) - Thursday, 11 August 2011, 10:14 GMT
Maybe I'm not accurately said that.
I have already mentioned that I found an unlocking the tray before ejecting it in the current version of Linux kernel, in the module "cdrom", CDROMEJECT ioctl() handler.
But now more CDROMEJECT ioctl() not handled by this module.
I think that is associated with the transition to the SCSI emulation for IDE-drives.
Comment by Tom Gundersen (tomegun) - Thursday, 11 August 2011, 10:31 GMT
Thanks.
Comment by Natrio (natrio) - Friday, 12 August 2011, 06:36 GMT
At the request of some members of the commutity archlinux.org.ru placed in AUR:
http://aur.archlinux.org/packages.php?ID=51466
Comment by Kooothor (Kooothor) - Monday, 15 August 2011, 00:48 GMT
I confirm the natrio package works fine and solves the issue :)
Thanks !
Comment by Tobias Powalowski (tpowa) - Wednesday, 17 August 2011, 07:58 GMT Comment by Natrio (natrio) - Wednesday, 17 August 2011, 08:06 GMT
I didn't take patches from Fedora, all by myself:)
Now I'll see if everything is done there.
Comment by Natrio (natrio) - Wednesday, 17 August 2011, 08:49 GMT
I have compiled a package with all patches from Fedora. These people did a great job, but the CD-ROM eject command they have still not working:
--------------
$ eject -v
eject: using default device `cdrom'
eject: device name is `cdrom'
eject: expanded name is `/dev/cdrom'
eject: `/dev/cdrom' is a link to `/dev/sr0'
eject: `/dev/sr0' is not mounted
eject: `/dev/sr0' is not a mount point
eject: checking if device "/dev/sr0" has a removable or hotpluggable flag
eject: `/dev/sr0' is not a multipartition device
eject: trying to eject `/dev/sr0' using CD-ROM eject command
eject: CD-ROM eject command failed
eject: trying to eject `/dev/sr0' using SCSI commands
eject: SCSI eject succeeded
--------------
And the "toggle" command doesn't work at all:
--------------
$ eject -vT
eject: using default device `cdrom'
eject: device name is `cdrom'
eject: expanded name is `/dev/cdrom'
eject: `/dev/cdrom' is a link to `/dev/sr0'
eject: `/dev/sr0' is not mounted
eject: `/dev/sr0' is not a mount point
eject: checking if device "/dev/sr0" has a removable or hotpluggable flag
eject: `/dev/sr0' is not a multipartition device
eject: toggling tray
ioctl: Input/output error
--------------
I'll try to combine it all.
Comment by Natrio (natrio) - Wednesday, 17 August 2011, 15:38 GMT
This is a package with all six patches from Fedora and 7th from me.
http://aur.archlinux.org/packages.php?ID=51466
This unlocks a tray before ejecting it in the ToggleTray() and EjectCdrom() functions.
Comment by Natrio (natrio) - Friday, 19 August 2011, 09:04 GMT
I replaced the "opendevice" patch from Fedora to my "openrw" patch, because I consider it necessary to inform (in "verbose" mode) about impossibility to open a device to write, to make it clear why the SCSI commands fail.
The "unlock" patch has been updated for compatibility with changes in the source.
The AUR package has been updated too.
http://aur.archlinux.org/packages.php?ID=51466

Loading...